decantr 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +868 -0
- package/CHANGELOG.md +255 -0
- package/CLAUDE.md +178 -0
- package/LICENSE +21 -0
- package/README.md +229 -0
- package/cli/art.js +127 -0
- package/cli/commands/a11y.js +61 -0
- package/cli/commands/audit.js +225 -0
- package/cli/commands/build.js +38 -0
- package/cli/commands/dev.js +18 -0
- package/cli/commands/doctor.js +197 -0
- package/cli/commands/figma-sync.js +48 -0
- package/cli/commands/figma-tokens.js +55 -0
- package/cli/commands/generate.js +26 -0
- package/cli/commands/init.js +116 -0
- package/cli/commands/lint.js +209 -0
- package/cli/commands/mcp.js +530 -0
- package/cli/commands/migrate.js +175 -0
- package/cli/commands/test.js +38 -0
- package/cli/commands/validate.js +354 -0
- package/cli/index.js +113 -0
- package/package.json +95 -0
- package/reference/atoms.md +517 -0
- package/reference/behaviors.md +384 -0
- package/reference/build-tooling.md +275 -0
- package/reference/color-guidelines.md +965 -0
- package/reference/component-lifecycle.md +137 -0
- package/reference/compound-spacing.md +95 -0
- package/reference/decantation-process.md +499 -0
- package/reference/dev-server-routes.md +93 -0
- package/reference/form-system.md +253 -0
- package/reference/i18n.md +336 -0
- package/reference/icons.md +576 -0
- package/reference/llm-primer.md +953 -0
- package/reference/plugins.md +252 -0
- package/reference/registry-consumption.md +76 -0
- package/reference/router.md +217 -0
- package/reference/shells.md +116 -0
- package/reference/spatial-guidelines.md +541 -0
- package/reference/ssr.md +234 -0
- package/reference/state-data.md +215 -0
- package/reference/state-patterns.md +166 -0
- package/reference/state.md +194 -0
- package/reference/style-system.md +110 -0
- package/reference/tokens.md +460 -0
- package/src/app.js +19 -0
- package/src/chart/_animate.js +266 -0
- package/src/chart/_base.js +109 -0
- package/src/chart/_data.js +209 -0
- package/src/chart/_format.js +106 -0
- package/src/chart/_interact.js +364 -0
- package/src/chart/_palette.js +105 -0
- package/src/chart/_renderer.js +52 -0
- package/src/chart/_scene.js +262 -0
- package/src/chart/_shared.js +371 -0
- package/src/chart/index.js +637 -0
- package/src/chart/layouts/_layout-base.js +328 -0
- package/src/chart/layouts/cartesian.js +148 -0
- package/src/chart/layouts/hierarchy.js +562 -0
- package/src/chart/layouts/polar.js +101 -0
- package/src/chart/renderers/canvas.js +179 -0
- package/src/chart/renderers/svg.js +256 -0
- package/src/chart/renderers/webgpu.js +715 -0
- package/src/chart/types/_type-base.js +26 -0
- package/src/chart/types/area.js +134 -0
- package/src/chart/types/bar.js +173 -0
- package/src/chart/types/box-plot.js +125 -0
- package/src/chart/types/bubble.js +63 -0
- package/src/chart/types/candlestick.js +115 -0
- package/src/chart/types/chord.js +85 -0
- package/src/chart/types/combination.js +108 -0
- package/src/chart/types/funnel.js +68 -0
- package/src/chart/types/gauge.js +163 -0
- package/src/chart/types/heatmap.js +98 -0
- package/src/chart/types/histogram.js +71 -0
- package/src/chart/types/line.js +111 -0
- package/src/chart/types/org-chart.js +93 -0
- package/src/chart/types/pie.js +81 -0
- package/src/chart/types/radar.js +96 -0
- package/src/chart/types/radial.js +68 -0
- package/src/chart/types/range-area.js +55 -0
- package/src/chart/types/range-bar.js +61 -0
- package/src/chart/types/sankey.js +73 -0
- package/src/chart/types/scatter.js +66 -0
- package/src/chart/types/sparkline.js +81 -0
- package/src/chart/types/sunburst.js +69 -0
- package/src/chart/types/swimlane.js +88 -0
- package/src/chart/types/treemap.js +62 -0
- package/src/chart/types/waterfall.js +100 -0
- package/src/components/_base.js +1658 -0
- package/src/components/_behaviors.js +1140 -0
- package/src/components/_primitives.js +534 -0
- package/src/components/_qr-encoder.js +539 -0
- package/src/components/accordion.js +207 -0
- package/src/components/affix.js +62 -0
- package/src/components/alert-dialog.js +75 -0
- package/src/components/alert.js +47 -0
- package/src/components/aspect-ratio.js +24 -0
- package/src/components/avatar-group.js +55 -0
- package/src/components/avatar.js +38 -0
- package/src/components/back-top.js +75 -0
- package/src/components/badge.js +74 -0
- package/src/components/banner.js +68 -0
- package/src/components/breadcrumb.js +162 -0
- package/src/components/button.js +115 -0
- package/src/components/calendar.js +131 -0
- package/src/components/card.js +192 -0
- package/src/components/carousel.js +98 -0
- package/src/components/cascader.js +261 -0
- package/src/components/checkbox.js +80 -0
- package/src/components/chip.js +81 -0
- package/src/components/code-block.js +82 -0
- package/src/components/collapsible.js +50 -0
- package/src/components/color-palette.js +438 -0
- package/src/components/color-picker.js +314 -0
- package/src/components/combobox.js +181 -0
- package/src/components/command.js +174 -0
- package/src/components/comment.js +206 -0
- package/src/components/context-menu.js +76 -0
- package/src/components/data-table.js +724 -0
- package/src/components/date-picker.js +217 -0
- package/src/components/date-range-picker.js +244 -0
- package/src/components/datetime-picker.js +271 -0
- package/src/components/descriptions.js +68 -0
- package/src/components/drawer.js +179 -0
- package/src/components/dropdown.js +88 -0
- package/src/components/empty.js +41 -0
- package/src/components/float-button.js +90 -0
- package/src/components/form.js +106 -0
- package/src/components/hover-card.js +49 -0
- package/src/components/icon.js +87 -0
- package/src/components/image.js +97 -0
- package/src/components/index.js +117 -0
- package/src/components/input-group.js +75 -0
- package/src/components/input-number.js +155 -0
- package/src/components/input-otp.js +178 -0
- package/src/components/input.js +91 -0
- package/src/components/kbd.js +36 -0
- package/src/components/label.js +25 -0
- package/src/components/list.js +118 -0
- package/src/components/masked-input.js +236 -0
- package/src/components/mentions.js +165 -0
- package/src/components/menu.js +259 -0
- package/src/components/message.js +80 -0
- package/src/components/modal.js +147 -0
- package/src/components/navigation-menu.js +166 -0
- package/src/components/notification.js +84 -0
- package/src/components/pagination.js +104 -0
- package/src/components/placeholder.js +132 -0
- package/src/components/popconfirm.js +70 -0
- package/src/components/popover.js +58 -0
- package/src/components/progress.js +61 -0
- package/src/components/qrcode.js +251 -0
- package/src/components/radiogroup.js +120 -0
- package/src/components/range-slider.js +176 -0
- package/src/components/rate.js +186 -0
- package/src/components/resizable.js +83 -0
- package/src/components/result.js +57 -0
- package/src/components/scroll-area.js +43 -0
- package/src/components/segmented.js +97 -0
- package/src/components/select.js +165 -0
- package/src/components/separator.js +31 -0
- package/src/components/shell.js +407 -0
- package/src/components/skeleton.js +39 -0
- package/src/components/slider.js +141 -0
- package/src/components/sortable-list.js +176 -0
- package/src/components/space.js +42 -0
- package/src/components/spinner.js +112 -0
- package/src/components/splitter.js +147 -0
- package/src/components/statistic.js +136 -0
- package/src/components/steps.js +99 -0
- package/src/components/switch.js +95 -0
- package/src/components/table.js +44 -0
- package/src/components/tabs.js +216 -0
- package/src/components/tag.js +115 -0
- package/src/components/textarea.js +82 -0
- package/src/components/time-picker.js +153 -0
- package/src/components/time-range-picker.js +170 -0
- package/src/components/timeline.js +226 -0
- package/src/components/toast.js +71 -0
- package/src/components/toggle.js +213 -0
- package/src/components/tooltip.js +57 -0
- package/src/components/tour.js +159 -0
- package/src/components/transfer.js +163 -0
- package/src/components/tree-select.js +274 -0
- package/src/components/tree.js +141 -0
- package/src/components/typography.js +136 -0
- package/src/components/upload.js +118 -0
- package/src/components/visually-hidden.js +20 -0
- package/src/components/watermark.js +124 -0
- package/src/core/index.js +539 -0
- package/src/core/lifecycle.js +69 -0
- package/src/css/atoms.js +651 -0
- package/src/css/components.js +940 -0
- package/src/css/derive.js +1296 -0
- package/src/css/index.js +265 -0
- package/src/css/runtime.js +268 -0
- package/src/css/styles/addons/bioluminescent.js +93 -0
- package/src/css/styles/addons/clay.js +70 -0
- package/src/css/styles/addons/clean.js +57 -0
- package/src/css/styles/addons/command-center.js +143 -0
- package/src/css/styles/addons/dopamine.js +83 -0
- package/src/css/styles/addons/editorial.js +80 -0
- package/src/css/styles/addons/glassmorphism.js +99 -0
- package/src/css/styles/addons/liquid-glass.js +105 -0
- package/src/css/styles/addons/prismatic.js +100 -0
- package/src/css/styles/addons/retro.js +63 -0
- package/src/css/styles/auradecantism.js +96 -0
- package/src/css/theme-registry.js +444 -0
- package/src/data/entity.js +281 -0
- package/src/data/index.js +13 -0
- package/src/data/persist.js +225 -0
- package/src/data/query.js +839 -0
- package/src/data/realtime.js +299 -0
- package/src/data/url.js +177 -0
- package/src/data/worker.js +134 -0
- package/src/explorer/archetypes.js +243 -0
- package/src/explorer/atoms.js +228 -0
- package/src/explorer/charts.js +497 -0
- package/src/explorer/components.js +129 -0
- package/src/explorer/foundations.js +949 -0
- package/src/explorer/icons.js +178 -0
- package/src/explorer/patterns.js +247 -0
- package/src/explorer/recipes.js +194 -0
- package/src/explorer/shared/pattern-examples.js +1337 -0
- package/src/explorer/shared/showcase-renderer.js +958 -0
- package/src/explorer/shared/spec-table.js +41 -0
- package/src/explorer/shared/usage-links.js +87 -0
- package/src/explorer/shell-config.js +10 -0
- package/src/explorer/shells.js +551 -0
- package/src/explorer/styles.js +161 -0
- package/src/explorer/tokens.js +262 -0
- package/src/explorer/tools.js +525 -0
- package/src/form/index.js +804 -0
- package/src/i18n/index.js +251 -0
- package/src/icons/essential.js +479 -0
- package/src/icons/index.js +53 -0
- package/src/plugins/index.js +282 -0
- package/src/registry/archetypes/content-site.json +71 -0
- package/src/registry/archetypes/docs-explorer.json +23 -0
- package/src/registry/archetypes/ecommerce.json +104 -0
- package/src/registry/archetypes/financial-dashboard.json +77 -0
- package/src/registry/archetypes/index.json +41 -0
- package/src/registry/archetypes/portfolio.json +82 -0
- package/src/registry/archetypes/recipe-community.json +159 -0
- package/src/registry/archetypes/saas-dashboard.json +86 -0
- package/src/registry/architect/cross-cutting.json +45 -0
- package/src/registry/architect/domains/ecommerce.json +294 -0
- package/src/registry/architect/domains/financial-services.json +302 -0
- package/src/registry/architect/index.json +26 -0
- package/src/registry/architect/traits.json +379 -0
- package/src/registry/atoms.json +16 -0
- package/src/registry/chart-showcase.json +160 -0
- package/src/registry/chart.json +136 -0
- package/src/registry/components.json +8616 -0
- package/src/registry/core.json +216 -0
- package/src/registry/css.json +319 -0
- package/src/registry/data.json +135 -0
- package/src/registry/foundations.json +11 -0
- package/src/registry/icons.json +463 -0
- package/src/registry/index.json +101 -0
- package/src/registry/patterns/activity-feed.json +37 -0
- package/src/registry/patterns/article-content.json +27 -0
- package/src/registry/patterns/auth-form.json +37 -0
- package/src/registry/patterns/author-card.json +20 -0
- package/src/registry/patterns/card-grid.json +127 -0
- package/src/registry/patterns/category-nav.json +26 -0
- package/src/registry/patterns/chart-grid.json +36 -0
- package/src/registry/patterns/chat-interface.json +37 -0
- package/src/registry/patterns/checklist-card.json +55 -0
- package/src/registry/patterns/comparison-panel.json +27 -0
- package/src/registry/patterns/component-showcase.json +24 -0
- package/src/registry/patterns/contact-form.json +31 -0
- package/src/registry/patterns/cta-section.json +20 -0
- package/src/registry/patterns/data-table.json +37 -0
- package/src/registry/patterns/detail-header.json +83 -0
- package/src/registry/patterns/detail-panel.json +27 -0
- package/src/registry/patterns/explorer-shell.json +22 -0
- package/src/registry/patterns/filter-bar.json +33 -0
- package/src/registry/patterns/filter-sidebar.json +27 -0
- package/src/registry/patterns/form-sections.json +110 -0
- package/src/registry/patterns/goal-tracker.json +27 -0
- package/src/registry/patterns/hero.json +107 -0
- package/src/registry/patterns/index.json +47 -0
- package/src/registry/patterns/kpi-grid.json +36 -0
- package/src/registry/patterns/media-gallery.json +20 -0
- package/src/registry/patterns/order-history.json +20 -0
- package/src/registry/patterns/pagination.json +19 -0
- package/src/registry/patterns/photo-to-recipe.json +36 -0
- package/src/registry/patterns/pipeline-tracker.json +28 -0
- package/src/registry/patterns/post-list.json +27 -0
- package/src/registry/patterns/pricing-table.json +32 -0
- package/src/registry/patterns/scorecard.json +28 -0
- package/src/registry/patterns/search-bar.json +20 -0
- package/src/registry/patterns/specimen-grid.json +19 -0
- package/src/registry/patterns/stat-card.json +55 -0
- package/src/registry/patterns/stats-bar.json +55 -0
- package/src/registry/patterns/steps-card.json +55 -0
- package/src/registry/patterns/table-of-contents.json +19 -0
- package/src/registry/patterns/testimonials.json +21 -0
- package/src/registry/patterns/timeline.json +27 -0
- package/src/registry/patterns/token-inspector.json +21 -0
- package/src/registry/patterns/wizard.json +27 -0
- package/src/registry/recipe-auradecantism.json +69 -0
- package/src/registry/recipe-clean.json +65 -0
- package/src/registry/recipe-command-center.json +78 -0
- package/src/registry/router.json +73 -0
- package/src/registry/schema/README.md +197 -0
- package/src/registry/skeletons.json +259 -0
- package/src/registry/state.json +137 -0
- package/src/registry/tokens.json +40 -0
- package/src/router/hash.js +17 -0
- package/src/router/history.js +18 -0
- package/src/router/index.js +598 -0
- package/src/ssr/index.js +922 -0
- package/src/state/arrays.js +181 -0
- package/src/state/devtools.js +647 -0
- package/src/state/index.js +498 -0
- package/src/state/middleware.js +288 -0
- package/src/state/scheduler.js +206 -0
- package/src/state/store.js +300 -0
- package/src/tags/index.js +19 -0
- package/src/tannins/auth.js +396 -0
- package/src/test/dom.js +352 -0
- package/src/test/index.js +62 -0
- package/src/test/state.js +306 -0
- package/tools/a11y-audit.js +487 -0
- package/tools/analyzer.js +315 -0
- package/tools/audit.js +706 -0
- package/tools/builder.js +1422 -0
- package/tools/css-extract.js +188 -0
- package/tools/dev-server.js +316 -0
- package/tools/dts-gen.js +1260 -0
- package/tools/figma-components.js +329 -0
- package/tools/figma-patterns.js +516 -0
- package/tools/figma-plugin/code.js +453 -0
- package/tools/figma-plugin/manifest.json +14 -0
- package/tools/figma-plugin/ui.html +268 -0
- package/tools/figma-render.js +293 -0
- package/tools/figma-tokens.js +712 -0
- package/tools/figma-upload.js +318 -0
- package/tools/generate.js +738 -0
- package/tools/icons.js +133 -0
- package/tools/init-templates.js +265 -0
- package/tools/install-hooks.sh +5 -0
- package/tools/migrations/0.5.0.js +53 -0
- package/tools/migrations/0.6.0.js +95 -0
- package/tools/minify.js +170 -0
- package/tools/pre-commit +4 -0
- package/tools/registry.js +662 -0
- package/tools/reset-playground.js +61 -0
- package/tools/starter-templates/content-site/app.js +49 -0
- package/tools/starter-templates/content-site/essence.js +19 -0
- package/tools/starter-templates/content-site/pages.js +31 -0
- package/tools/starter-templates/ecommerce/app.js +50 -0
- package/tools/starter-templates/ecommerce/essence.js +19 -0
- package/tools/starter-templates/ecommerce/pages.js +31 -0
- package/tools/starter-templates/landing-page/app.js +38 -0
- package/tools/starter-templates/landing-page/essence.js +18 -0
- package/tools/starter-templates/landing-page/pages.js +21 -0
- package/tools/starter-templates/portfolio/app.js +45 -0
- package/tools/starter-templates/portfolio/essence.js +19 -0
- package/tools/starter-templates/portfolio/pages.js +33 -0
- package/tools/starter-templates/saas-dashboard/app.js +70 -0
- package/tools/starter-templates/saas-dashboard/essence.js +19 -0
- package/tools/starter-templates/saas-dashboard/pages.js +31 -0
- package/tools/verify-pack.js +203 -0
- package/types/chart.d.ts +77 -0
- package/types/components.d.ts +587 -0
- package/types/core.d.ts +89 -0
- package/types/css.d.ts +149 -0
- package/types/data.d.ts +238 -0
- package/types/form.d.ts +164 -0
- package/types/i18n.d.ts +51 -0
- package/types/icons.d.ts +27 -0
- package/types/index.d.ts +13 -0
- package/types/router.d.ts +116 -0
- package/types/ssr.d.ts +102 -0
- package/types/state.d.ts +83 -0
- package/types/tags.d.ts +62 -0
- package/types/tannins.d.ts +63 -0
- package/types/test.d.ts +48 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { css } from 'decantr/css';
|
|
2
|
+
import { tags } from 'decantr/tags';
|
|
3
|
+
import { Chip, Separator, Tabs } from 'decantr/components';
|
|
4
|
+
import { injectExplorerCSS } from './styles.js';
|
|
5
|
+
injectExplorerCSS();
|
|
6
|
+
|
|
7
|
+
const { div, h2, h3, h4, p, span, section, code, strong, a } = tags;
|
|
8
|
+
|
|
9
|
+
let archetypesData = {};
|
|
10
|
+
let archetypesLoaded = false;
|
|
11
|
+
|
|
12
|
+
async function loadArchetypes() {
|
|
13
|
+
if (archetypesLoaded) return archetypesData;
|
|
14
|
+
try {
|
|
15
|
+
const indexResp = await fetch('/__decantr/registry/archetypes/index.json');
|
|
16
|
+
const index = await indexResp.json();
|
|
17
|
+
const entries = Object.entries(index.archetypes || index);
|
|
18
|
+
for (const [id, meta] of entries) {
|
|
19
|
+
if (typeof meta !== 'object' || !meta.file) continue;
|
|
20
|
+
try {
|
|
21
|
+
const resp = await fetch(`/__decantr/registry/archetypes/${meta.file}`);
|
|
22
|
+
archetypesData[id] = await resp.json();
|
|
23
|
+
archetypesData[id]._meta = meta;
|
|
24
|
+
} catch { archetypesData[id] = { _meta: meta, pages: [] }; }
|
|
25
|
+
}
|
|
26
|
+
archetypesLoaded = true;
|
|
27
|
+
} catch {
|
|
28
|
+
archetypesLoaded = true;
|
|
29
|
+
}
|
|
30
|
+
return archetypesData;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function ArchetypeDetail(archetypeId, navigateTo) {
|
|
34
|
+
const container = div({ class: css('_flex _col _gap4') },
|
|
35
|
+
p({ class: css('_body _fgmutedfg') }, 'Loading archetype...')
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
loadArchetypes().then(archetypes => {
|
|
39
|
+
const arch = archetypes[archetypeId];
|
|
40
|
+
container.innerHTML = '';
|
|
41
|
+
|
|
42
|
+
if (!arch) {
|
|
43
|
+
container.appendChild(p({ class: css('_fgmutedfg _body') }, `Archetype "${archetypeId}" not found.`));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const tabs = Tabs({
|
|
48
|
+
tabs: [
|
|
49
|
+
{
|
|
50
|
+
id: 'features',
|
|
51
|
+
label: 'Features',
|
|
52
|
+
content: () => featuresTab(arch, navigateTo)
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'api',
|
|
56
|
+
label: 'API',
|
|
57
|
+
content: () => apiTab(arch)
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
container.appendChild(
|
|
63
|
+
div({ class: css('_flex _col _gap1 _mb3') },
|
|
64
|
+
h2({ class: css('_heading4') }, arch._meta?.name || archetypeId),
|
|
65
|
+
p({ class: css('_body _fgmutedfg') }, arch._meta?.description || 'Domain application blueprint.')
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
container.appendChild(tabs);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return container;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function featuresTab(arch, navigateTo) {
|
|
75
|
+
const sections = [];
|
|
76
|
+
const pages = arch.pages || [];
|
|
77
|
+
|
|
78
|
+
// Live page rendering (first page)
|
|
79
|
+
if (pages.length > 0) {
|
|
80
|
+
const page = pages[0];
|
|
81
|
+
const blend = page.blend || page.default_blend || [];
|
|
82
|
+
const surface = page.surface || '_flex _col _gap4 _p4';
|
|
83
|
+
|
|
84
|
+
sections.push(
|
|
85
|
+
div({ class: css('_flex _col _gap4') },
|
|
86
|
+
h4({ class: css('_heading5 _mb3') }, `Live Page: ${page.id}`),
|
|
87
|
+
div({ class: css(surface + ' _border _bcborder _radius _minh[300px]') },
|
|
88
|
+
...(Array.isArray(blend) ? blend : []).map(row => {
|
|
89
|
+
if (typeof row === 'string') {
|
|
90
|
+
return div({ class: css('_p4 _bgmuted/10 _radius _border _bcborder') },
|
|
91
|
+
span({ class: css('_caption _fgmutedfg') }, row)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (row.cols) {
|
|
95
|
+
return div({ class: css(`_grid _gc${row.cols.length} _gap4`) },
|
|
96
|
+
...row.cols.map(col =>
|
|
97
|
+
div({ class: css('_p4 _bgmuted/10 _radius _border _bcborder') },
|
|
98
|
+
span({ class: css('_caption _fgmutedfg') }, col)
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return div({ class: css('_p2 _bgmuted/10 _radius') }, code({}, JSON.stringify(row)));
|
|
104
|
+
})
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Pages overview
|
|
111
|
+
if (pages.length > 0) {
|
|
112
|
+
sections.push(Separator({}));
|
|
113
|
+
sections.push(
|
|
114
|
+
div({ class: css('_flex _col _gap4') },
|
|
115
|
+
h4({ class: css('_heading5 _mb3') }, `${pages.length} Pages`),
|
|
116
|
+
...pages.map(page =>
|
|
117
|
+
div({ class: css('_p3 _border _bcborder _radius _flex _col _gap2') },
|
|
118
|
+
div({ class: css('_flex _jcsb _aic') },
|
|
119
|
+
strong({ class: css('_heading6') }, page.id),
|
|
120
|
+
span({ class: css('_caption _fgmutedfg') }, `skeleton: ${page.skeleton || '—'}`)
|
|
121
|
+
),
|
|
122
|
+
page.patterns ? div({ class: css('_flex _gap1 _wrap') },
|
|
123
|
+
...(page.patterns || []).map(pat =>
|
|
124
|
+
Chip({
|
|
125
|
+
label: pat,
|
|
126
|
+
variant: 'outline',
|
|
127
|
+
size: 'sm',
|
|
128
|
+
onclick: () => navigateTo(`/patterns/${pat}`)
|
|
129
|
+
})
|
|
130
|
+
)
|
|
131
|
+
) : null,
|
|
132
|
+
page.blend ? div({ class: css('_flex _col _gap1') },
|
|
133
|
+
span({ class: css('_caption _fgmutedfg') }, 'Blend:'),
|
|
134
|
+
code({ class: css('_caption _wsprewrap') }, JSON.stringify(page.blend || page.default_blend, null, 2))
|
|
135
|
+
) : null
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (sections.length === 0) {
|
|
143
|
+
return div({ class: css('_fgmutedfg _body') }, 'No pages defined.');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return div({ class: css('_flex _col _gap8') }, ...sections);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function apiTab(arch) {
|
|
150
|
+
const sections = [];
|
|
151
|
+
const tannins = arch.tannins || arch.organs || [];
|
|
152
|
+
const suggested = arch.suggested_vintage || {};
|
|
153
|
+
|
|
154
|
+
// Tannins
|
|
155
|
+
if (tannins.length > 0) {
|
|
156
|
+
sections.push(
|
|
157
|
+
div({ class: css('_flex _col _gap2') },
|
|
158
|
+
h4({ class: css('_heading6') }, 'Tannins (Functional Systems)'),
|
|
159
|
+
div({ class: css('_flex _gap2 _wrap') },
|
|
160
|
+
...tannins.map(t => Chip({ label: t, variant: 'outline', size: 'sm' }))
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Suggested vintage
|
|
167
|
+
if (Object.keys(suggested).length > 0) {
|
|
168
|
+
sections.push(
|
|
169
|
+
div({ class: css('_flex _col _gap2') },
|
|
170
|
+
h4({ class: css('_heading6') }, 'Suggested Vintage'),
|
|
171
|
+
div({ class: css('_flex _col _gap1') },
|
|
172
|
+
...Object.entries(suggested).map(([key, val]) =>
|
|
173
|
+
div({}, strong({ class: css('_caption') }, key + ': '), span({ class: css('_caption _fgmutedfg') }, Array.isArray(val) ? val.join(', ') : String(val)))
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Skeletons
|
|
181
|
+
if (arch.skeletons) {
|
|
182
|
+
sections.push(
|
|
183
|
+
div({ class: css('_flex _col _gap2') },
|
|
184
|
+
h4({ class: css('_heading6') }, 'Skeletons'),
|
|
185
|
+
...Object.entries(arch.skeletons).map(([name, desc]) =>
|
|
186
|
+
div({}, strong({ class: css('_caption') }, name + ': '), span({ class: css('_caption _fgmutedfg') }, typeof desc === 'string' ? desc : JSON.stringify(desc)))
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (sections.length === 0) {
|
|
193
|
+
return div({ class: css('_fgmutedfg _body') }, 'No API metadata available.');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return div({ class: css('_flex _col _gap6') }, ...sections);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function ArchetypeListView(navigateTo) {
|
|
200
|
+
const container = div({ class: css('_flex _col _gap4') },
|
|
201
|
+
h2({ class: css('_heading4') }, 'Archetypes'),
|
|
202
|
+
p({ class: css('_body _fgmutedfg') }, 'Loading archetypes...')
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
loadArchetypes().then(archetypes => {
|
|
206
|
+
container.innerHTML = '';
|
|
207
|
+
container.appendChild(h2({ class: css('_heading4 _mb2') }, 'Archetypes'));
|
|
208
|
+
container.appendChild(p({ class: css('_body _fgmutedfg _mb3') }, 'Domain application blueprints with pre-mapped pages, patterns, and tannins.'));
|
|
209
|
+
|
|
210
|
+
const grid = div({ class: 'de-card-grid' });
|
|
211
|
+
for (const [id, arch] of Object.entries(archetypes)) {
|
|
212
|
+
grid.appendChild(div({
|
|
213
|
+
class: 'de-card-item',
|
|
214
|
+
onclick: () => navigateTo(`/archetypes/${id}`)
|
|
215
|
+
},
|
|
216
|
+
div({ class: css('_flex _col _gap2') },
|
|
217
|
+
h3({ class: css('_heading6') }, arch._meta?.name || id),
|
|
218
|
+
p({ class: css('_caption _fgmutedfg') }, arch._meta?.description || ''),
|
|
219
|
+
div({ class: css('_flex _gap2') },
|
|
220
|
+
span({ class: css('_caption _fgmutedfg') }, `${(arch.pages || []).length} pages`),
|
|
221
|
+
span({ class: css('_caption _fgmutedfg') }, `${(arch.tannins || arch.organs || []).length} tannins`)
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
));
|
|
225
|
+
}
|
|
226
|
+
container.appendChild(grid);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return container;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export async function loadArchetypeItems() {
|
|
233
|
+
try {
|
|
234
|
+
const resp = await fetch('/__decantr/registry/archetypes/index.json');
|
|
235
|
+
const data = await resp.json();
|
|
236
|
+
const entries = data.archetypes || data;
|
|
237
|
+
return Object.entries(entries)
|
|
238
|
+
.filter(([, meta]) => typeof meta === 'object' && meta.file)
|
|
239
|
+
.map(([id, meta]) => ({ id, label: meta.name || id }));
|
|
240
|
+
} catch {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { createSignal, createEffect } from 'decantr/state';
|
|
2
|
+
import { css } from 'decantr/css';
|
|
3
|
+
import { tags } from 'decantr/tags';
|
|
4
|
+
import { Input } from 'decantr/components';
|
|
5
|
+
import { injectExplorerCSS } from './styles.js';
|
|
6
|
+
injectExplorerCSS();
|
|
7
|
+
|
|
8
|
+
const { div, h2, p, span, section, code, small } = tags;
|
|
9
|
+
|
|
10
|
+
// Atom categories — loaded from registry, cached locally
|
|
11
|
+
let atomCategories = null;
|
|
12
|
+
|
|
13
|
+
// ─── CSS property hints for common atom prefixes ─────────────
|
|
14
|
+
const ATOM_CSS_HINTS = {
|
|
15
|
+
_flex: 'display: flex', _grid: 'display: grid', _block: 'display: block',
|
|
16
|
+
_inline: 'display: inline', _relative: 'position: relative', _absolute: 'position: absolute',
|
|
17
|
+
_fixed: 'position: fixed', _sticky: 'position: sticky', _none: 'display: none',
|
|
18
|
+
_invisible: 'visibility: hidden',
|
|
19
|
+
_p: 'padding', _m: 'margin', _gap: 'gap', _sp: 'spacing scale',
|
|
20
|
+
_w: 'width', _h: 'height', _min: 'min-width/height', _max: 'max-width/height',
|
|
21
|
+
_text: 'font-size', _heading: 'heading scale', _body: 'body text', _caption: 'caption text',
|
|
22
|
+
_label: 'label text', _overline: 'overline text', _fw: 'font-weight', _lh: 'line-height',
|
|
23
|
+
_ls: 'letter-spacing', _font: 'font-family', _fontmono: 'font-family: monospace',
|
|
24
|
+
_fg: 'color', _bg: 'background', _bc: 'border-color',
|
|
25
|
+
_border: 'border', _b1: 'border: 1px', _radius: 'border-radius',
|
|
26
|
+
_shadow: 'box-shadow', _opacity: 'opacity', _blur: 'filter: blur', _overflow: 'overflow',
|
|
27
|
+
_pointer: 'cursor: pointer', _select: 'user-select', _cursor: 'cursor', _transition: 'transition',
|
|
28
|
+
_aic: 'align-items: center', _jcc: 'justify-content: center', _jcsb: 'justify-content: space-between',
|
|
29
|
+
_center: 'center both', _tc: 'text-align: center', _tl: 'text-align: left', _tr: 'text-align: right',
|
|
30
|
+
'_sm:': '@media (sm)', '_md:': '@media (md)', '_lg:': '@media (lg)', '_xl:': '@media (xl)',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function getHint(atom) {
|
|
34
|
+
if (ATOM_CSS_HINTS[atom]) return ATOM_CSS_HINTS[atom];
|
|
35
|
+
// Match longest prefix
|
|
36
|
+
for (const [prefix, hint] of Object.entries(ATOM_CSS_HINTS)) {
|
|
37
|
+
if (atom.startsWith(prefix)) return hint;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─── Preview strategy per category ───────────────────────────
|
|
43
|
+
|
|
44
|
+
function renderChildBoxes(sizes) {
|
|
45
|
+
return (sizes || [1, 2, 3]).map(i =>
|
|
46
|
+
div({ class: css(`_w[var(--d-sp-6)] _h[var(--d-sp-4)] _bgprimary _r[var(--d-radius-sm)] _op[${0.4 + i * 0.2}]`) })
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function renderLayoutPreview(atom) {
|
|
51
|
+
if (atom === '_none' || atom === '_invisible') {
|
|
52
|
+
return div({ class: css('_p2 _fgmutedfg _caption') }, ATOM_CSS_HINTS[atom] || atom);
|
|
53
|
+
}
|
|
54
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
55
|
+
div({ class: css(atom + ' _gap2 _p2 _border _bcborder _minh[var(--d-sp-8)] _r[var(--d-radius-inner)]') },
|
|
56
|
+
...renderChildBoxes()
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function renderSpacingPreview(atom) {
|
|
62
|
+
// Show nested boxes to visualize padding/margin/gap
|
|
63
|
+
if (atom.startsWith('_gap')) {
|
|
64
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
65
|
+
div({ class: css('_flex ' + atom + ' _border _bcborder _p1 _r[var(--d-radius-inner)]') },
|
|
66
|
+
div({ class: css('_w[var(--d-sp-4)] _h[var(--d-sp-4)] _bgprimary _r[var(--d-radius-sm)] _op[0.7]') }),
|
|
67
|
+
div({ class: css('_w[var(--d-sp-4)] _h[var(--d-sp-4)] _bgprimary _r[var(--d-radius-sm)] _op[0.9]') }),
|
|
68
|
+
div({ class: css('_w[var(--d-sp-4)] _h[var(--d-sp-4)] _bgprimary _r[var(--d-radius-sm)]') })
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
// Padding/margin: show a box with the spacing applied
|
|
73
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
74
|
+
div({ class: css(atom + ' _border _bcborder _bg[var(--d-primary-subtle)] _r[var(--d-radius-inner)]') },
|
|
75
|
+
div({ class: css('_bgprimary _r[var(--d-radius-sm)] _h[var(--d-sp-4)] _op[0.6]') })
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function renderSizingPreview(atom) {
|
|
81
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
82
|
+
div({ class: css(atom + ' _border _bcborder _bg[var(--d-primary-subtle)] _r[var(--d-radius-inner)] _minh[var(--d-sp-4)]') })
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function renderTypographyPreview(atom) {
|
|
87
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
88
|
+
span({ class: css(atom) }, 'Aa Bb 123')
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function renderColorPreview(atom) {
|
|
93
|
+
if (atom.startsWith('_fg')) {
|
|
94
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
95
|
+
span({ class: css(atom + ' _heading5') }, 'Aa')
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (atom.startsWith('_bg')) {
|
|
99
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
100
|
+
div({ class: css(atom + ' _radius _w[var(--d-sp-10)] _h[var(--d-sp-6)] _b1 _bcborder') })
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
// border-color
|
|
104
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
105
|
+
div({ class: css(atom + ' _border _radius _w[var(--d-sp-10)] _h[var(--d-sp-6)] _bw[2px]') })
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function renderBorderPreview(atom) {
|
|
110
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
111
|
+
div({ class: css(atom + ' _bcborder _w[var(--d-sp-10)] _h[var(--d-sp-6)] _bg[var(--d-primary-subtle)]') })
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function renderEffectPreview(atom) {
|
|
116
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
117
|
+
div({ class: css(atom + ' _radius _w[var(--d-sp-10)] _h[var(--d-sp-6)] _bg[var(--d-surface-1)] _b1 _bcborder') })
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function renderAlignmentPreview(atom) {
|
|
122
|
+
return div({ class: 'de-atom-preview ' + css('_p2') },
|
|
123
|
+
div({ class: css('_flex ' + atom + ' _gap1 _border _bcborder _p1 _h[var(--d-sp-10)] _r[var(--d-radius-inner)]') },
|
|
124
|
+
div({ class: css('_w[var(--d-sp-3)] _h[var(--d-sp-3)] _bgprimary _r[var(--d-radius-sm)] _op[0.6]') }),
|
|
125
|
+
div({ class: css('_w[var(--d-sp-3)] _h[var(--d-sp-6)] _bgprimary _r[var(--d-radius-sm)] _op[0.8]') }),
|
|
126
|
+
div({ class: css('_w[var(--d-sp-3)] _h[var(--d-sp-4)] _bgprimary _r[var(--d-radius-sm)]') })
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function renderBadgePreview(atom) {
|
|
132
|
+
return div({ class: css('_p2 _fgmutedfg _caption') }, getHint(atom) || atom);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Map category IDs to preview strategies
|
|
136
|
+
const PREVIEW_STRATEGY = {
|
|
137
|
+
layout: renderLayoutPreview,
|
|
138
|
+
spacing: renderSpacingPreview,
|
|
139
|
+
sizing: renderSizingPreview,
|
|
140
|
+
typography: renderTypographyPreview,
|
|
141
|
+
color: renderColorPreview,
|
|
142
|
+
border: renderBorderPreview,
|
|
143
|
+
effects: renderEffectPreview,
|
|
144
|
+
interaction: renderBadgePreview,
|
|
145
|
+
alignment: renderAlignmentPreview,
|
|
146
|
+
responsive: renderBadgePreview,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// ─── Data loading ────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
async function loadAtomCategories() {
|
|
152
|
+
if (atomCategories) return atomCategories;
|
|
153
|
+
try {
|
|
154
|
+
const resp = await fetch('/__decantr/registry/atoms.json');
|
|
155
|
+
const data = await resp.json();
|
|
156
|
+
atomCategories = {};
|
|
157
|
+
for (const [id, cat] of Object.entries(data.categories || {})) {
|
|
158
|
+
atomCategories[id] = { label: cat.label, prefix: cat.prefixes || cat.prefix || [] };
|
|
159
|
+
}
|
|
160
|
+
} catch {
|
|
161
|
+
atomCategories = {};
|
|
162
|
+
}
|
|
163
|
+
return atomCategories;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ─── Explorer component ──────────────────────────────────────
|
|
167
|
+
|
|
168
|
+
export function AtomsExplorer(category) {
|
|
169
|
+
const [filter, setFilter] = createSignal('');
|
|
170
|
+
const container = div({ id: 'atoms-' + category, class: css('_flex _col _gap4') },
|
|
171
|
+
p({ class: css('_body _fgmutedfg') }, 'Loading atoms...')
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
loadAtomCategories().then(categories => {
|
|
175
|
+
const cat = categories[category];
|
|
176
|
+
const catLabel = cat ? cat.label : 'All';
|
|
177
|
+
const previewFn = PREVIEW_STRATEGY[category] || renderBadgePreview;
|
|
178
|
+
|
|
179
|
+
const filterInput = Input({
|
|
180
|
+
placeholder: `Filter ${catLabel.toLowerCase()} atoms...`,
|
|
181
|
+
oninput: (e) => setFilter(e.target.value)
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const grid = div({ class: 'de-atom-grid' });
|
|
185
|
+
|
|
186
|
+
function renderAtoms() {
|
|
187
|
+
grid.innerHTML = '';
|
|
188
|
+
const prefixes = cat ? cat.prefix : [];
|
|
189
|
+
const q = filter().toLowerCase();
|
|
190
|
+
const filtered = q ? prefixes.filter(a => a.toLowerCase().includes(q)) : prefixes;
|
|
191
|
+
|
|
192
|
+
for (const atom of filtered) {
|
|
193
|
+
const hint = getHint(atom);
|
|
194
|
+
const card = div({ class: 'de-atom-card' },
|
|
195
|
+
code({ class: 'de-atom-name' }, atom),
|
|
196
|
+
hint ? small({ class: 'de-atom-hint' }, hint) : null,
|
|
197
|
+
previewFn(atom)
|
|
198
|
+
);
|
|
199
|
+
grid.appendChild(card);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (filtered.length === 0) {
|
|
203
|
+
grid.appendChild(p({ class: css('_fgmutedfg _body _p4') }, 'No atoms matching filter.'));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
createEffect(() => { filter(); renderAtoms(); });
|
|
208
|
+
|
|
209
|
+
container.innerHTML = '';
|
|
210
|
+
container.appendChild(section({ class: css('_flex _col _gap4') },
|
|
211
|
+
div({ class: css('_flex _col _gap1') },
|
|
212
|
+
h2({ class: css('_heading4') }, `Atoms — ${catLabel}`),
|
|
213
|
+
p({ class: css('_body _fgmutedfg') }, '1000+ atomic CSS utility classes. Each prefixed with _ for namespace safety.')
|
|
214
|
+
),
|
|
215
|
+
filterInput,
|
|
216
|
+
grid
|
|
217
|
+
));
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return container;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export async function loadAtomItems() {
|
|
224
|
+
const categories = await loadAtomCategories();
|
|
225
|
+
return Object.entries(categories).map(([id, cat]) => ({
|
|
226
|
+
id, label: cat.label
|
|
227
|
+
}));
|
|
228
|
+
}
|