Skip to content

Commit

Permalink
chore(docs): update @getcanary/web dependency to version 1.0.0-rc.15
Browse files Browse the repository at this point in the history
  • Loading branch information
yujonglee committed Oct 6, 2024
1 parent 1816dcc commit 2dd03a4
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 34 deletions.
13 changes: 10 additions & 3 deletions js/apps/docs/components/CEM.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<script setup lang="ts">
import type { Package, CustomElementDeclaration } from "custom-elements-manifest/schema";
import type {
Package,
CustomElementDeclaration,
} from "custom-elements-manifest/schema";
import cem from "@getcanary/web/custom-elements.json";
Expand Down Expand Up @@ -31,7 +34,7 @@ const components = (cem as Package).modules.reduce(
>
<h2 :id="name" class="text-3xl">{{ name }}</h2>
<a
:href="`https://github.com/fastrepl/canary/blob/main/js/packages/web/${name}.ts`"
:href="`https://github.com/fastrepl/canary/blob/main/js/packages/web/src/components/${name}.ts`"
target="_blank"
class="text-sm"
>
Expand Down Expand Up @@ -59,8 +62,12 @@ const components = (cem as Package).modules.reduce(
<template v-if="declaration.attributes">
<h3>Attributes</h3>
<ul class="list-disc list-inside">
<li v-for="attr in declaration.attributes">
<li
v-for="attr in declaration.attributes"
class="flex flex-row gap-2 items-center"
>
<code>{{ attr.name }}</code>
<span class="text-sm italic">{{ attr.type.text }}</span>
</li>
</ul>
</template>
Expand Down
10 changes: 9 additions & 1 deletion js/apps/docs/components/CloudSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const tabs = JSON.stringify([
{ name: "Docs", pattern: "**/getcanary.dev/**" },
{ name: "Github", pattern: "**/github.com/**" },
]);
const sync = JSON.stringify([
{ tag: "Local", pattern: "**/docs/local/**" },
{ tag: "Cloud", pattern: "**/docs/cloud/**" },
]);
const sources = ["canary_webpage", "canary_issue"];
</script>

Expand All @@ -45,7 +49,11 @@ const sources = ["canary_webpage", "canary_issue"];
<canary-modal>
<canary-trigger-searchbar slot="trigger"></canary-trigger-searchbar>
<canary-content slot="content">
<canary-filter-tags slot="head" :tags="tags"></canary-filter-tags>
<canary-filter-tags
slot="head"
:tags="tags"
:url-sync="sync"
></canary-filter-tags>
<canary-input slot="input" autofocus></canary-input>
<canary-search slot="mode">
<canary-callout-discord
Expand Down
41 changes: 41 additions & 0 deletions js/apps/docs/contents/docs/cloud/integrations/astro.md
Original file line number Diff line number Diff line change
@@ -1 +1,42 @@
# Astro

[Astro](https://astro.build) is web framework for content-driven websites.

## Two steps to integrate

### Step 1: Install `@getcanary/web`

```bash
npm install @getcanary/web
```

### Step 2: Create search component

You can customize and place it anywhere you want.

```html{12}
<script>
import '@getcanary/web/components/canary-root.js'
import '@getcanary/web/components/canary-provider-pagefind.js'
import '@getcanary/web/components/canary-modal.js'
import '@getcanary/web/components/canary-trigger-searchbar.js'
import '@getcanary/web/components/canary-content.js'
import '@getcanary/web/components/canary-input.js'
import '@getcanary/web/components/canary-search.js'
import '@getcanary/web/components/canary-search-results.js'
</script>
<canary-root framework="astro">
<canary-provider-pagefind>
<canary-modal>
<canary-trigger-searchbar slot="trigger"></canary-trigger-searchbar>
<canary-content slot="content">
<canary-input slot="input"></canary-input>
<canary-search slot="mode">
<canary-search-results slot="body"></canary-search-results>
</canary-search>
</canary-content>
</canary-modal>
</canary-provider-pagefind>
</canary-root>
```
7 changes: 7 additions & 0 deletions js/apps/docs/contents/docs/open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Open

## NPM Downloads

## Github

### Stars
14 changes: 14 additions & 0 deletions js/apps/docs/contents/docs/reference/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,18 @@

# Components

::: tip

For visual reference and code example, please refer to our [Storybook](https://storybook.getcanary.dev).

:::

This page is generated from [`custom-elements-manifest`](https://custom-elements-manifest.open-wc.org/analyzer/getting-started/#supported-jsdoc).

If you find something missing here, there's three places to fix it:

1. [`CEM.vue`](https://github.com/fastrepl/canary/blob/main/js/apps/docs/components/CEM.vue) for rendering the data.
2. [Each component's source code](https://github.com/fastrepl/canary/tree/main/js/packages/web/src/components) for adding the missing data.
3. [`vite.config.ts`](https://github.com/fastrepl/canary/blob/main/js/packages/web/vite.config.ts) for adding the missing component.

<CEM />
4 changes: 4 additions & 0 deletions js/apps/docs/contents/docs/reference/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import { data as docusaurus } from "../../../data/version_docusaurus.data.js";

## `@getcanary/web`

[npm](https://www.npmjs.com/package/@getcanary/web)

```bash-vue
npm install @getcanary/web@{{ web.version }}
```

## `@getcanary/docusaurus-theme-search-pagefind`

[npm](https://www.npmjs.com/package/@getcanary/docusaurus-theme-search-pagefind)

```bash-vue
npm install @getcanary/docusaurus-theme-search-pagefind@{{ docusaurus.version }}
```
2 changes: 2 additions & 0 deletions js/apps/docs/contents/docs/why.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const packages = {

We're fully [open-source](https://github.com/fastrepl/canary), and encourage anyone to contribute to our UI components. Also, we put a lot of effort into making the **core parts of `Canary` as modular as possible**.

## Attention to detail, for technical docs

## Tiny components that works anywhere

`Canary` use [Web components](https://developer.mozilla.org/en-US/docs/Web/Web_Components), so browsers know how to render it.
Expand Down
2 changes: 1 addition & 1 deletion js/apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"vue": "^3.4.35"
},
"dependencies": {
"@getcanary/web": "^1.0.0-rc.14",
"@getcanary/web": "^1.0.0-rc.15",
"@mux/blurup": "^0.2.3",
"@mux/mux-player": "^3.0.0",
"@vercel/analytics": "^1.3.1",
Expand Down
4 changes: 2 additions & 2 deletions js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/packages/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@getcanary/web",
"version": "1.0.0-rc.14",
"version": "1.0.0-rc.15",
"license": "MIT",
"type": "module",
"main": "dist/components/canary-root.js",
Expand Down
115 changes: 89 additions & 26 deletions js/packages/web/src/components/canary-filter-tags.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LitElement, css, html, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators.js";
import { customElement, property, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";

import pm from "picomatch";
Expand All @@ -12,82 +12,139 @@ const NAME = "canary-filter-tags";

@customElement(NAME)
export class CanaryFilterTags extends LitElement {
/**
* @attr {string} tags - comma separated list of tags
*/
@property({ converter: StringArray })
tags: string[] = [];

/**
* @attr {object} url-sync - sync tags with URL
*/
@property({ type: Object, attribute: "url-sync" })
syncURL?: TagUrlSyncDefinition;

@property({ type: String, attribute: "local-storage-key" })
localStorageKey?: string;

@property({ type: String })
selected = "";
@state()
private _selected = "";

connectedCallback() {
super.connectedCallback();
this._ensureTagsConverted();
this._initializeSelected();

window.addEventListener("popstate", this._handlePopState.bind(this));
this._patchHistory();
}

disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener("popstate", this._handlePopState.bind(this));
}

updated(changed: PropertyValues<this>) {
if (changed.has("selected") && this.localStorageKey) {
localStorage.setItem(this.localStorageKey, this.selected);
updated(changed: PropertyValues) {
if (changed.has("_selected") && this.localStorageKey) {
localStorage.setItem(this.localStorageKey, this._selected);
}

if (changed.has("selected")) {
if (changed.has("_selected")) {
this.dispatchEvent(
createEvent({ type: "set_query", data: { tags: [this.selected] } }),
createEvent({ type: "set_query", data: { tags: [this._selected] } }),
);
}
}

private _handlePopState() {
this._initializeSelected();
}

private _patchHistory() {
if (window["__history_patched__"]) {
return;
}

window["__history_patched__"] = true;

window.history.pushState = new Proxy(window.history.pushState, {
apply: (
target: History["pushState"],
thisArg: History,
argArray: Parameters<History["pushState"]>,
): ReturnType<History["pushState"]> => {
const url =
typeof argArray[2] === "string"
? new URL(argArray[2], window.location.href).href
: window.location.href;

this._initializeSelected(url);
return target.apply(thisArg, argArray);
},
});
}

private _ensureTagsConverted() {
if (typeof this.tags === "string") {
this.tags = StringArray.fromAttribute(this.tags, null);
}
}

private _initializeSelected() {
if (this.selected) {
private _initializeSelected(url?: string) {
if (this._handleSyncURL(url)) {
return;
}

if (this.syncURL) {
const { hostname, pathname } = new URL(window.location.href);
const found = this.syncURL.find(({ pattern }) =>
pm(pattern)(`${hostname}${pathname}`),
);
if (this._applyLocalStorage()) {
return;
}

this._selected = this.tags[0];
}

if (found) {
this.selected = found.tag;
return;
}
private _handleSyncURL(url?: string) {
if (!this.syncURL) {
return false;
}

const { hostname, pathname } = new URL(url ?? window.location.href);
const found = this.syncURL.find(({ pattern }) =>
pm(pattern)(`${hostname}${pathname}`),
);

if (found) {
this._selected = found.tag;
return true;
}

return false;
}

private _applyLocalStorage() {
if (!this.localStorageKey) {
this.selected = this.tags[0];
return;
return false;
}

const storedValue = localStorage.getItem(this.localStorageKey);
if (storedValue && this.tags.includes(storedValue)) {
this.selected = storedValue;
} else {
this.selected = this.tags[0];
this._selected = storedValue;
return true;
}

return false;
}

render() {
return html`
<div class="container" part="container">
${this.tags.map((tag) => {
const selected = tag === this.selected;
const selected = tag === this._selected;
return html`<button
@click=${() => (this.selected = tag)}
@click=${() => (this._selected = tag)}
part=${["tag", selected ? "active" : "inactive"].join(" ")}
class=${classMap({ tag: true, active: selected })}
aria-label=${`${tag}-tag`}
>
${tag}
</button>`;
Expand Down Expand Up @@ -135,3 +192,9 @@ export class CanaryFilterTags extends LitElement {
}
`;
}

declare global {
interface Window {
__history_patched__?: boolean;
}
}
11 changes: 11 additions & 0 deletions js/packages/web/src/components/canary-search-match-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ import { MODAL_CLOSE_EVENT } from "./canary-modal";

const NAME = "canary-search-match-base";

/**
* @csspart container - Container of the match
*
* @slot content-before - Content before the match
* @slot url - URL of the match
* @slot title-icon - Icon for the title
* @slot title - Title of the match
* @slot title-badge - Badge displayed next to the title
* @slot excerpt - Excerpt of the match
* @slot sub-results - Sub-results related to the match
*/
@customElement(NAME)
export class CanarySearchMatchBase extends LitElement {
@property({ type: String })
Expand Down

0 comments on commit 2dd03a4

Please sign in to comment.