@sableui/react 0.0.0-stage → 0.1.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 +157 -0
- package/CHANGELOG.md +50 -0
- package/CONTRIBUTING.md +221 -0
- package/DESIGN.md +548 -0
- package/LICENSE +21 -0
- package/README.md +194 -2
- package/THIRD_PARTY_NOTICES.md +44 -0
- package/bin/sable-lint.mjs +0 -0
- package/bin/sable.mjs +1223 -0
- package/dist/_contract-CYScOdf5.d.ts +150 -0
- package/dist/chunk-3IWZYBGH.js +398 -0
- package/dist/chunk-5Z5KLOAU.js +167 -0
- package/dist/chunk-7MG4SHYX.js +15 -0
- package/dist/chunk-ADLLDWLW.js +15 -0
- package/dist/chunk-EP55KSYA.js +14 -0
- package/dist/chunk-J23ELQQZ.js +9396 -0
- package/dist/chunk-JI7WJP2L.js +286 -0
- package/dist/chunk-K7RUHUGC.js +14 -0
- package/dist/chunk-KO3NAEBF.js +15 -0
- package/dist/chunk-L4IEIQQA.js +14 -0
- package/dist/chunk-L6Y46C62.js +270 -0
- package/dist/chunk-NEQNXI2G.js +25 -0
- package/dist/chunk-PAOZBZME.js +40 -0
- package/dist/chunk-RWP4XBSK.js +139 -0
- package/dist/chunk-SRQWQUTW.js +63 -0
- package/dist/chunk-YXBOYWBN.js +15 -0
- package/dist/foundations/index.d.ts +88 -0
- package/dist/foundations/index.js +792 -0
- package/dist/icon/index.d.ts +60 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon-sets/brands.d.ts +44 -0
- package/dist/icon-sets/brands.js +147 -0
- package/dist/icon-sets/reicon.d.ts +8 -0
- package/dist/icon-sets/reicon.js +1 -0
- package/dist/index.d.ts +7013 -0
- package/dist/index.js +15462 -0
- package/dist/ios/chrome.css +83 -0
- package/dist/ios/frame.css +5 -0
- package/dist/ios/index.d.ts +70 -0
- package/dist/ios/index.js +313 -0
- package/dist/ios/preview.d.ts +64 -0
- package/dist/ios/preview.js +133 -0
- package/dist/ios/styles.css +77 -0
- package/dist/layout/index.d.ts +280 -0
- package/dist/layout/index.js +2 -0
- package/dist/meta-6dUzgC6M.d.ts +205 -0
- package/dist/patterns/index.d.ts +36 -0
- package/dist/patterns/index.js +934 -0
- package/dist/presets/index.d.ts +37 -0
- package/dist/presets/index.js +117 -0
- package/dist/registry-CyL28OzJ.d.ts +28 -0
- package/dist/styles.css +1893 -0
- package/dist/theme-provider-BWcizhAt.d.ts +105 -0
- package/dist/themes/atelier/atelier.css +213 -0
- package/dist/themes/atelier/index.d.ts +9 -0
- package/dist/themes/atelier/index.js +1 -0
- package/dist/themes/base/base.css +443 -0
- package/dist/themes/base/index.d.ts +9 -0
- package/dist/themes/base/index.js +1 -0
- package/dist/themes/ember/ember.css +270 -0
- package/dist/themes/ember/index.d.ts +9 -0
- package/dist/themes/ember/index.js +1 -0
- package/dist/themes/index.d.ts +10 -0
- package/dist/themes/index.js +8 -0
- package/dist/themes/meridian/index.d.ts +9 -0
- package/dist/themes/meridian/index.js +1 -0
- package/dist/themes/meridian/meridian.css +255 -0
- package/dist/themes/poppy/index.d.ts +6 -0
- package/dist/themes/poppy/index.js +1 -0
- package/dist/themes/poppy/poppy.css +174 -0
- package/dist/themes/prism/index.d.ts +6 -0
- package/dist/themes/prism/index.js +1 -0
- package/dist/themes/prism/prism.css +183 -0
- package/dist/themes/verdant/index.d.ts +9 -0
- package/dist/themes/verdant/index.js +1 -0
- package/dist/themes/verdant/verdant.css +210 -0
- package/dist/themes.css +30 -0
- package/llms/components/accordion.md +93 -0
- package/llms/components/app-header.md +70 -0
- package/llms/components/app-shell.md +117 -0
- package/llms/components/attachment.md +105 -0
- package/llms/components/avatar.md +141 -0
- package/llms/components/badge.md +117 -0
- package/llms/components/banner.md +119 -0
- package/llms/components/bottom-nav.md +80 -0
- package/llms/components/breadcrumbs.md +75 -0
- package/llms/components/browser.md +67 -0
- package/llms/components/bubble.md +119 -0
- package/llms/components/button.md +199 -0
- package/llms/components/calendar.md +75 -0
- package/llms/components/card.md +135 -0
- package/llms/components/carousel.md +87 -0
- package/llms/components/chat-composer.md +126 -0
- package/llms/components/checkbox-card.md +98 -0
- package/llms/components/checkbox.md +90 -0
- package/llms/components/code-block.md +81 -0
- package/llms/components/code.md +62 -0
- package/llms/components/collapsible.md +83 -0
- package/llms/components/color-field.md +100 -0
- package/llms/components/combobox.md +119 -0
- package/llms/components/command-menu.md +158 -0
- package/llms/components/context-card.md +73 -0
- package/llms/components/context-menu.md +79 -0
- package/llms/components/data-table.md +99 -0
- package/llms/components/date-picker.md +97 -0
- package/llms/components/description.md +96 -0
- package/llms/components/destructive-action-modal.md +76 -0
- package/llms/components/dialog.md +127 -0
- package/llms/components/dots-menu.md +64 -0
- package/llms/components/empty-state.md +113 -0
- package/llms/components/entity.md +67 -0
- package/llms/components/feedback.md +63 -0
- package/llms/components/fieldset.md +106 -0
- package/llms/components/file-dropzone.md +103 -0
- package/llms/components/form.md +111 -0
- package/llms/components/gliding-highlight.md +84 -0
- package/llms/components/inline-status.md +62 -0
- package/llms/components/input.md +127 -0
- package/llms/components/kbd.md +57 -0
- package/llms/components/label.md +73 -0
- package/llms/components/marker.md +99 -0
- package/llms/components/marquee.md +66 -0
- package/llms/components/menu.md +122 -0
- package/llms/components/message-scroller.md +110 -0
- package/llms/components/message.md +114 -0
- package/llms/components/meter.md +124 -0
- package/llms/components/middle-truncate.md +62 -0
- package/llms/components/note.md +81 -0
- package/llms/components/notification-badge.md +67 -0
- package/llms/components/number-field.md +70 -0
- package/llms/components/otp-field.md +101 -0
- package/llms/components/page-header.md +76 -0
- package/llms/components/page-loader.md +67 -0
- package/llms/components/pagination.md +92 -0
- package/llms/components/panel-group.md +120 -0
- package/llms/components/panel-section.md +122 -0
- package/llms/components/phone.md +70 -0
- package/llms/components/pill.md +73 -0
- package/llms/components/popover.md +79 -0
- package/llms/components/progress.md +98 -0
- package/llms/components/radio-card.md +90 -0
- package/llms/components/radio.md +86 -0
- package/llms/components/relative-time.md +60 -0
- package/llms/components/scroller.md +88 -0
- package/llms/components/scrub-field.md +97 -0
- package/llms/components/search-input.md +84 -0
- package/llms/components/select.md +106 -0
- package/llms/components/separator.md +70 -0
- package/llms/components/settings-menu.md +139 -0
- package/llms/components/sheet.md +97 -0
- package/llms/components/show-more.md +59 -0
- package/llms/components/side-nav.md +106 -0
- package/llms/components/sidebar.md +87 -0
- package/llms/components/skeleton.md +62 -0
- package/llms/components/slider.md +114 -0
- package/llms/components/spinner.md +87 -0
- package/llms/components/status-bar.md +91 -0
- package/llms/components/status-dot.md +70 -0
- package/llms/components/stepper.md +125 -0
- package/llms/components/streaming-text.md +86 -0
- package/llms/components/switch.md +87 -0
- package/llms/components/table.md +112 -0
- package/llms/components/tabs.md +84 -0
- package/llms/components/textarea.md +88 -0
- package/llms/components/theme-selector.md +95 -0
- package/llms/components/theme-switcher.md +71 -0
- package/llms/components/thinking-orb.md +91 -0
- package/llms/components/toast.md +130 -0
- package/llms/components/toggle.md +95 -0
- package/llms/components/toolbar.md +168 -0
- package/llms/components/tooltip.md +93 -0
- package/llms/components/tree.md +227 -0
- package/llms/components/video.md +66 -0
- package/llms/components/workspace.md +138 -0
- package/llms/foundations/accessibility.md +60 -0
- package/llms/foundations/motion.md +96 -0
- package/llms/foundations/scrolling.md +41 -0
- package/llms/foundations/shape.md +73 -0
- package/llms/foundations/spacing.md +82 -0
- package/llms/foundations/surfaces.md +69 -0
- package/llms/foundations/typography.md +120 -0
- package/llms/layout/aspect-box.md +37 -0
- package/llms/layout/bleed.md +31 -0
- package/llms/layout/center.md +37 -0
- package/llms/layout/columns.md +51 -0
- package/llms/layout/grid-overlay.md +40 -0
- package/llms/layout/grid.md +47 -0
- package/llms/layout/page.md +39 -0
- package/llms/layout/region.md +49 -0
- package/llms/layout/row.md +40 -0
- package/llms/layout/safe-area.md +37 -0
- package/llms/layout/spacer.md +39 -0
- package/llms/layout/split-pane.md +41 -0
- package/llms/layout/stack.md +39 -0
- package/llms/patterns/auth-page.md +68 -0
- package/llms/patterns/brand-landing-page.md +423 -0
- package/llms/patterns/chat-panel.md +210 -0
- package/llms/patterns/dashboard-page.md +170 -0
- package/llms/patterns/feed-page.md +103 -0
- package/llms/patterns/landing-page.md +122 -0
- package/llms/patterns/list-detail-page.md +100 -0
- package/llms/patterns/settings-page.md +121 -0
- package/llms/reference/token-intent.md +324 -0
- package/llms/reference/utilities.md +129 -0
- package/llms/tasks/adding-a-component.md +113 -0
- package/llms/tasks/auditing-an-app.md +216 -0
- package/llms/tasks/building-a-page.md +109 -0
- package/llms/tasks/building-a-tool.md +141 -0
- package/llms/tasks/building-an-ios-prototype.md +105 -0
- package/llms/tasks/building-with-sable.md +73 -0
- package/llms/tasks/choosing-a-component.md +109 -0
- package/llms/tasks/converting-an-app.md +139 -0
- package/llms/tasks/creating-a-preset.md +43 -0
- package/llms/tasks/creating-design-assets.md +96 -0
- package/llms/tasks/designing-a-surface.md +115 -0
- package/llms/tasks/developing-taste.md +157 -0
- package/llms/tasks/getting-started.md +63 -0
- package/llms/tasks/learning-from-builds.md +74 -0
- package/llms/tasks/reviewing-a-design.md +114 -0
- package/llms/tasks/reviewing-a-journey.md +84 -0
- package/llms/tasks/reviewing-motion.md +92 -0
- package/llms/tasks/using-presets.md +87 -0
- package/llms/taste/asset-plan.template.json +53 -0
- package/llms/taste/composition-follows-content.md +20 -0
- package/llms/taste/hierarchy-is-a-relationship.md +22 -0
- package/llms/taste/lessons.json +57 -0
- package/llms/taste/motion-needs-a-reason.md +21 -0
- package/llms/taste/surface-states-travel-together.md +20 -0
- package/llms-full.txt +14906 -0
- package/llms.txt +405 -0
- package/package.json +185 -3
- package/registry.json +18812 -0
- package/scripts/agent-setup.mjs +54 -0
- package/scripts/design-atlas.mjs +221 -0
- package/scripts/design-directions.mjs +123 -0
- package/scripts/design-memory.mjs +166 -0
- package/scripts/design-preferences.mjs +227 -0
- package/scripts/design-presets.mjs +48 -0
- package/scripts/grade.mjs +509 -0
- package/scripts/lint-rules.mjs +1065 -0
- package/scripts/review-evidence.mjs +120 -0
- package/scripts/skeleton.mjs +248 -0
- package/skills/entry/SKILL.md +34 -0
- package/skills/sable/SKILL.md +187 -0
- package/skills/sable/agents/openai.yaml +6 -0
- package/targets/ios.json +982 -0
- package/third-party/reicon-LICENSE.txt +20 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { T as ThemeManifest } from '../_contract-CYScOdf5.js';
|
|
2
|
+
|
|
3
|
+
/** The public theme vocabulary. Presets never need component overrides. */
|
|
4
|
+
declare const PRESET_TOKEN_NAMES: readonly string[];
|
|
5
|
+
interface SablePreset {
|
|
6
|
+
schemaVersion: 1;
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
revision: number;
|
|
10
|
+
sableVersion: string;
|
|
11
|
+
defaultMode: "light" | "dark";
|
|
12
|
+
fonts: {
|
|
13
|
+
sans: string;
|
|
14
|
+
mono: string;
|
|
15
|
+
display?: string;
|
|
16
|
+
};
|
|
17
|
+
/** Apply alongside tokens: composition, imagery, interaction and motion guidance. */
|
|
18
|
+
direction: string;
|
|
19
|
+
references?: {
|
|
20
|
+
source: string;
|
|
21
|
+
observation: string;
|
|
22
|
+
method: "measured" | "estimated" | "derived" | "user-edited";
|
|
23
|
+
}[];
|
|
24
|
+
tokens: {
|
|
25
|
+
shared: Record<string, string>;
|
|
26
|
+
light: Record<string, string>;
|
|
27
|
+
dark: Record<string, string>;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Structural/contract validation; visual contrast and brief fit still need review. */
|
|
31
|
+
declare function validatePreset(input: unknown): string[];
|
|
32
|
+
declare function parsePreset(input: unknown): SablePreset;
|
|
33
|
+
declare function presetManifest(input: SablePreset): ThemeManifest;
|
|
34
|
+
/** Scoped CSS can coexist with built-in presets. Never changes :root globally. */
|
|
35
|
+
declare function presetCss(input: SablePreset): string;
|
|
36
|
+
|
|
37
|
+
export { PRESET_TOKEN_NAMES, type SablePreset, parsePreset, presetCss, presetManifest, validatePreset };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { SEMANTIC_TOKENS, WORKSPACE_SURFACE_TOKENS, DERIVED_EDGE_TOKENS, RADIUS_TOKENS, MOTION_TOKENS, TYPE_SCALE_TOKENS, TYPE_REFINEMENT_TOKENS, TYPE_OVERLINE_TOKENS, DENSITY_TOKENS, LAYERING_TOKENS, TYPE_UI_TOKENS } from '../chunk-JI7WJP2L.js';
|
|
2
|
+
|
|
3
|
+
// src/presets/index.ts
|
|
4
|
+
var PRESET_TOKEN_NAMES = [.../* @__PURE__ */ new Set([
|
|
5
|
+
...SEMANTIC_TOKENS,
|
|
6
|
+
...WORKSPACE_SURFACE_TOKENS.map((name) => `theme-${name}`),
|
|
7
|
+
...DERIVED_EDGE_TOKENS.map((name) => `theme-${name}`),
|
|
8
|
+
...WORKSPACE_SURFACE_TOKENS,
|
|
9
|
+
...DERIVED_EDGE_TOKENS,
|
|
10
|
+
...RADIUS_TOKENS,
|
|
11
|
+
...MOTION_TOKENS,
|
|
12
|
+
...TYPE_SCALE_TOKENS,
|
|
13
|
+
...TYPE_REFINEMENT_TOKENS,
|
|
14
|
+
...TYPE_OVERLINE_TOKENS,
|
|
15
|
+
...DENSITY_TOKENS,
|
|
16
|
+
...LAYERING_TOKENS,
|
|
17
|
+
...TYPE_UI_TOKENS,
|
|
18
|
+
"font-sans",
|
|
19
|
+
"font-mono",
|
|
20
|
+
"font-display",
|
|
21
|
+
"spacing",
|
|
22
|
+
"theme-shadow-sm",
|
|
23
|
+
"theme-shadow",
|
|
24
|
+
"theme-shadow-md",
|
|
25
|
+
"theme-shadow-lg",
|
|
26
|
+
"theme-shadow-xl"
|
|
27
|
+
])];
|
|
28
|
+
var tokenNames = new Set(PRESET_TOKEN_NAMES);
|
|
29
|
+
var record = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
30
|
+
var text = (value) => typeof value === "string" && value.trim().length > 0;
|
|
31
|
+
var safeCss = (value) => value.length <= 2048 && !/[;{}<>\\@]|\/\*|\*\/|!important|url\s*\(|expression\s*\(|REPLACE/i.test(value);
|
|
32
|
+
function validatePreset(input) {
|
|
33
|
+
if (!record(input)) return ["Preset must be a JSON object."];
|
|
34
|
+
const issues = [];
|
|
35
|
+
if (input.schemaVersion !== 1) issues.push("Unsupported preset schemaVersion; expected 1.");
|
|
36
|
+
if (typeof input.id !== "string" || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(input.id) || input.id.length > 64) issues.push("id must be a lowercase slug of at most 64 characters.");
|
|
37
|
+
if (!text(input.label) || input.label.length > 120) issues.push("label must contain 1\u2013120 characters.");
|
|
38
|
+
if (!Number.isSafeInteger(input.revision) || Number(input.revision) < 1) issues.push("revision must be a positive integer.");
|
|
39
|
+
if (typeof input.sableVersion !== "string" || !/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(input.sableVersion)) issues.push("sableVersion must record the package version used to author the preset.");
|
|
40
|
+
if (!["light", "dark"].includes(String(input.defaultMode))) issues.push("defaultMode must be light or dark.");
|
|
41
|
+
if (!text(input.direction) || input.direction.length > 16e3) issues.push("direction must contain design guidance, at most 16000 characters.");
|
|
42
|
+
if (!record(input.fonts) || !text(input.fonts.sans) || !text(input.fonts.mono)) issues.push("fonts must declare sans and mono stacks; the app loads their files.");
|
|
43
|
+
else for (const [role, stack] of Object.entries(input.fonts)) {
|
|
44
|
+
if (!["sans", "mono", "display"].includes(role) || !text(stack) || !safeCss(stack)) issues.push(`Invalid font stack: ${role}.`);
|
|
45
|
+
}
|
|
46
|
+
if (input.references !== void 0) {
|
|
47
|
+
if (!Array.isArray(input.references) || input.references.length > 50) issues.push("references must be an array of at most 50 observations.");
|
|
48
|
+
else input.references.forEach((item, index) => {
|
|
49
|
+
if (!record(item) || !text(item.source) || !text(item.observation) || !["measured", "estimated", "derived", "user-edited"].includes(String(item.method))) issues.push(`Invalid reference observation ${index + 1}.`);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!record(input.tokens)) return [...issues, "tokens must contain shared, light, and dark objects."];
|
|
53
|
+
const groups = input.tokens;
|
|
54
|
+
for (const group of ["shared", "light", "dark"]) {
|
|
55
|
+
const values = groups[group];
|
|
56
|
+
if (!record(values)) {
|
|
57
|
+
issues.push(`tokens.${group} must be an object.`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
for (const [name, value] of Object.entries(values)) {
|
|
61
|
+
if (!tokenNames.has(name)) issues.push(`Unknown Sable token in ${group}: ${name}. Use names without the -- prefix.`);
|
|
62
|
+
if (!text(value) || !safeCss(value)) issues.push(`Unsafe or empty CSS value for ${group}.${name}.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const mode of ["light", "dark"]) {
|
|
66
|
+
if (!record(groups[mode])) continue;
|
|
67
|
+
for (const name of SEMANTIC_TOKENS) {
|
|
68
|
+
if (!text(groups[mode][name])) issues.push(`Missing ${mode} semantic token: ${name}.`);
|
|
69
|
+
}
|
|
70
|
+
const values = { ...record(groups.shared) ? groups.shared : {}, ...groups[mode] };
|
|
71
|
+
for (const [name, value] of Object.entries(values)) {
|
|
72
|
+
if (typeof value !== "string") continue;
|
|
73
|
+
for (const match of value.matchAll(/var\(\s*--([\w-]+)/g)) {
|
|
74
|
+
if (!tokenNames.has(match[1])) issues.push(`${mode}.${name} depends on an unportable variable: --${match[1]}. Resolve palette values before saving.`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (record(input.fonts)) {
|
|
79
|
+
for (const [role, stack] of Object.entries(input.fonts)) for (const group of ["shared", "light", "dark"]) {
|
|
80
|
+
const values = groups[group];
|
|
81
|
+
if (record(values) && values[`font-${role}`] !== void 0 && values[`font-${role}`] !== stack) issues.push(`font-${role} differs from the declared font stack.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return issues;
|
|
85
|
+
}
|
|
86
|
+
function parsePreset(input) {
|
|
87
|
+
const issues = validatePreset(input);
|
|
88
|
+
if (issues.length) throw new Error(issues.join("\n"));
|
|
89
|
+
return input;
|
|
90
|
+
}
|
|
91
|
+
function presetManifest(input) {
|
|
92
|
+
const preset = parsePreset(input);
|
|
93
|
+
return { id: preset.id, label: preset.label, modes: ["light", "dark"], defaultMode: preset.defaultMode, fonts: preset.fonts };
|
|
94
|
+
}
|
|
95
|
+
function presetCss(input) {
|
|
96
|
+
const preset = parsePreset(input);
|
|
97
|
+
const selector = `[data-sable-theme="${preset.id}"]`;
|
|
98
|
+
const declarations = (values) => Object.entries(values).sort(([a], [b]) => a.localeCompare(b)).map(([name, value]) => {
|
|
99
|
+
const scaled = name.startsWith("motion-duration-") && !/var\(\s*--motion-(?:scale|duration-)/.test(value);
|
|
100
|
+
return ` --${name}: ${scaled ? `calc((${value}) * var(--motion-scale, 1))` : value};`;
|
|
101
|
+
}).join("\n");
|
|
102
|
+
const shared = { ...preset.tokens.shared, "font-sans": preset.fonts.sans, "font-mono": preset.fonts.mono, "font-display": preset.fonts.display ?? preset.fonts.sans };
|
|
103
|
+
return `${selector} {
|
|
104
|
+
${declarations({ ...shared, ...preset.tokens.light })}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
${selector}.dark, .dark ${selector}:not(.light) {
|
|
108
|
+
${declarations(preset.tokens.dark)}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
${selector}.light {
|
|
112
|
+
${declarations(preset.tokens.light)}
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { PRESET_TOKEN_NAMES, parsePreset, presetCss, presetManifest, validatePreset };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/** Icon weight/style. Open-ended so any set can define its own variants. */
|
|
4
|
+
type IconVariant = "regular" | "solid" | "brands" | (string & {});
|
|
5
|
+
interface IconRenderProps {
|
|
6
|
+
/** Semantic icon name (e.g. "heart", "gear", "chevron-down"). */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Resolved variant (the IconProvider's default is applied before this reaches the set). */
|
|
9
|
+
variant: IconVariant;
|
|
10
|
+
/** Spin animation. */
|
|
11
|
+
spin?: boolean;
|
|
12
|
+
/** Tailwind / size + color classes (e.g. "text-2xl text-muted-foreground"). */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Accessible label. When provided the set should expose the icon to AT; otherwise hide it. */
|
|
15
|
+
title?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* An icon set resolves a semantic name (+ variant) to a React node.
|
|
19
|
+
*
|
|
20
|
+
* Reicon supplies the default glyphs. A consuming app can override or extend
|
|
21
|
+
* the set through <IconProvider set={…}>.
|
|
22
|
+
*
|
|
23
|
+
* A set may render whatever it likes for a given name; it owns icon a11y
|
|
24
|
+
* (use `title` → role="img"/aria-label, else aria-hidden).
|
|
25
|
+
*/
|
|
26
|
+
type IconSet = (props: IconRenderProps) => ReactNode;
|
|
27
|
+
|
|
28
|
+
export type { IconSet as I, IconRenderProps as a, IconVariant as b };
|