@lucasvu/scope-ui 0.0.1 → 0.0.2

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/dist/index.js CHANGED
@@ -435,6 +435,7 @@ var Button = forwardRef(
435
435
  disabled,
436
436
  startIcon,
437
437
  endIcon,
438
+ block = false,
438
439
  className,
439
440
  style,
440
441
  children,
@@ -447,14 +448,14 @@ var Button = forwardRef(
447
448
  const describedBy = [helperId, errorId].filter(Boolean).join(" ") || void 0;
448
449
  const content = children ?? label;
449
450
  const isDisabled = disabled || loading;
450
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", style, children: [
451
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1", block && "w-full"), style, children: [
451
452
  /* @__PURE__ */ jsxs(
452
453
  "button",
453
454
  {
454
455
  ref,
455
456
  id: buttonId,
456
457
  type: type ?? "button",
457
- className: cn(buttonVariants({ variant, size, className })),
458
+ className: cn(buttonVariants({ variant, size, className }), block && "w-full"),
458
459
  disabled: isDisabled,
459
460
  "aria-describedby": describedBy,
460
461
  "aria-busy": loading || void 0,
@@ -875,6 +876,94 @@ var NumericInput = forwardRef(
875
876
  }
876
877
  );
877
878
  NumericInput.displayName = "NumericInput";
879
+ var textareaVariants = cva(
880
+ "flex min-h-[104px] w-full resize-y rounded-md border px-3 py-2 text-sm font-medium transition placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-60",
881
+ {
882
+ variants: {
883
+ variant: {
884
+ default: "border-input bg-background text-foreground hover:border-border",
885
+ ghost: "border-transparent bg-transparent text-foreground focus-visible:border-border/60",
886
+ outline: "border border-border bg-transparent text-foreground"
887
+ },
888
+ size: {
889
+ sm: "min-h-[88px] text-sm",
890
+ md: "min-h-[104px] text-sm",
891
+ lg: "min-h-[120px] text-base"
892
+ }
893
+ },
894
+ defaultVariants: {
895
+ variant: "default",
896
+ size: "md"
897
+ }
898
+ }
899
+ );
900
+ var Textarea = forwardRef(
901
+ ({
902
+ variant = "default",
903
+ size = "md",
904
+ label,
905
+ helperText,
906
+ errorMessage,
907
+ loading,
908
+ disabled,
909
+ className,
910
+ style,
911
+ textareaClassName,
912
+ id,
913
+ onChange,
914
+ onValueChange,
915
+ suffix,
916
+ rows,
917
+ ...rest
918
+ }, ref) => {
919
+ const generatedId = useId();
920
+ const textareaId = id ?? generatedId;
921
+ const helperId = helperText ? `${textareaId}-helper` : void 0;
922
+ const errorId = errorMessage ? `${textareaId}-error` : void 0;
923
+ const hasRightAccessory = Boolean(suffix) || Boolean(loading);
924
+ return /* @__PURE__ */ jsx(
925
+ FieldWrapper,
926
+ {
927
+ label,
928
+ helperText,
929
+ errorMessage,
930
+ helperId,
931
+ errorId,
932
+ htmlFor: textareaId,
933
+ className,
934
+ style,
935
+ children: /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
936
+ /* @__PURE__ */ jsx(
937
+ "textarea",
938
+ {
939
+ id: textareaId,
940
+ ref,
941
+ rows: rows ?? 4,
942
+ className: cn(
943
+ textareaVariants({ variant, size }),
944
+ hasRightAccessory && "pr-10",
945
+ textareaClassName
946
+ ),
947
+ disabled: disabled || loading,
948
+ "aria-invalid": Boolean(errorMessage),
949
+ "aria-describedby": [helperId, errorId].filter(Boolean).join(" ") || void 0,
950
+ onChange: (event) => {
951
+ onChange?.(event);
952
+ onValueChange?.(event.target.value);
953
+ },
954
+ ...rest
955
+ }
956
+ ),
957
+ hasRightAccessory ? /* @__PURE__ */ jsxs("span", { className: "pointer-events-none absolute right-3 top-3 flex items-center gap-2 text-muted-foreground", children: [
958
+ loading ? /* @__PURE__ */ jsx(LoadingSpinner, { size: "xs" }) : null,
959
+ suffix ? /* @__PURE__ */ jsx("span", { children: suffix }) : null
960
+ ] }) : null
961
+ ] })
962
+ }
963
+ );
964
+ }
965
+ );
966
+ Textarea.displayName = "Textarea";
878
967
  function Card({ className, ...props }) {
879
968
  return /* @__PURE__ */ jsx(
880
969
  "div",
@@ -1780,9 +1869,18 @@ function CheckMark() {
1780
1869
  function Form({ className, ...props }) {
1781
1870
  return /* @__PURE__ */ jsx("form", { className: cn("space-y-6", className), ...props });
1782
1871
  }
1783
- var FormField = forwardRef(({ className, ...props }, ref) => {
1784
- return /* @__PURE__ */ jsx("div", { ref, className: cn("grid gap-2", className), ...props });
1785
- });
1872
+ var FormField = forwardRef(
1873
+ ({ className, label, helperText, errorMessage, required, htmlFor, children, ...props }, ref) => {
1874
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("grid gap-2", className), ...props, children: [
1875
+ label ? /* @__PURE__ */ jsxs("label", { htmlFor, className: "text-sm font-semibold leading-none text-foreground", children: [
1876
+ label,
1877
+ required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-destructive", children: "*" }) : null
1878
+ ] }) : null,
1879
+ children,
1880
+ errorMessage ? /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errorMessage }) : helperText ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: helperText }) : null
1881
+ ] });
1882
+ }
1883
+ );
1786
1884
  FormField.displayName = "FormField";
1787
1885
  var FormItem = forwardRef(({ className, ...props }, ref) => {
1788
1886
  return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-2", className), ...props });
@@ -2009,6 +2107,13 @@ var SearchableSelect = forwardRef(
2009
2107
  return candidate.toLowerCase().includes(normalized);
2010
2108
  });
2011
2109
  }, [options, searchTerm]);
2110
+ const normalizeValue = useCallback(
2111
+ (raw) => {
2112
+ const match = options.find((option) => String(option.value) === raw);
2113
+ return match ? match.value : raw;
2114
+ },
2115
+ [options]
2116
+ );
2012
2117
  const handleOpenChange = useCallback(
2013
2118
  (next) => {
2014
2119
  setIsOpen(next);
@@ -2052,7 +2157,7 @@ var SearchableSelect = forwardRef(
2052
2157
  {
2053
2158
  value: value !== void 0 ? String(value) : void 0,
2054
2159
  defaultValue: defaultValue !== void 0 ? String(defaultValue) : void 0,
2055
- onValueChange: (next) => onChange?.(next),
2160
+ onValueChange: (next) => onChange?.(normalizeValue(next)),
2056
2161
  disabled: disabled || loading,
2057
2162
  onOpenChange: handleOpenChange,
2058
2163
  ...props,
@@ -6513,4 +6618,381 @@ function PageTitle2({
6513
6618
  );
6514
6619
  }
6515
6620
 
6516
- export { Alert, ArgonSidebar, AsyncCombobox, Badge, Breadcrumb, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Combobox, DataTable, FormField as Field, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Input, LineClampTooltip, Loading, main_fe_exports as MainFe, MultiSelect, NumericInput, OverflowTooltip, PageTitle, Pagination, SearchableSelect, SectionTitle, Select, Sidebar, SidebarItem, Stat, Table, TableBody, TableCell, TableHeader, TableRow, Tabs, Tooltip, TruncatedText, cn, defaultPermissionChecker, filterSidebarItems, hasActiveDescendant };
6621
+ // src/ai-manifest.ts
6622
+ var uiAiManifest = {
6623
+ packageName: "@lucasvu/scope-ui",
6624
+ styleImport: "@lucasvu/scope-ui/styles.css",
6625
+ rules: [
6626
+ "Import the stylesheet once at the app entry before rendering any component.",
6627
+ "Prefer the canonical component for each intent instead of mixing legacy MainFe components.",
6628
+ "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.",
6629
+ "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.",
6630
+ 'Always provide a stable rowKey to DataTable and use sortMode="server" when sorting happens on the backend.',
6631
+ "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.",
6632
+ "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."
6633
+ ],
6634
+ components: [
6635
+ {
6636
+ name: "Primary action",
6637
+ importName: "Button",
6638
+ purpose: "Render the main clickable action.",
6639
+ useWhen: [
6640
+ "Submitting a form",
6641
+ "Triggering create/save/confirm flows",
6642
+ "Need loading or block width support"
6643
+ ],
6644
+ avoidWhen: [
6645
+ "Pure navigation text links without button semantics"
6646
+ ],
6647
+ props: [
6648
+ { name: "variant", type: "'default' | 'secondary' | 'ghost' | 'outline' | 'destructive' | 'link' | 'confirm' | 'create'", description: "Chooses the visual emphasis." },
6649
+ { name: "size", type: "'sm' | 'md' | 'lg' | 'icon'", description: "Chooses the button size." },
6650
+ { name: "block", type: "boolean", description: "Expands the button to full width." },
6651
+ { name: "loading", type: "boolean", description: "Shows a spinner and disables interaction." }
6652
+ ],
6653
+ example: "<Button variant='create' block>Save changes</Button>",
6654
+ related: ["Alert", "Card"]
6655
+ },
6656
+ {
6657
+ name: "Single-line text input",
6658
+ importName: "Input",
6659
+ purpose: "Capture short text, email, password, number-like strings, or search text.",
6660
+ useWhen: [
6661
+ "A single text value is needed",
6662
+ "You need label/helper/error handling built in",
6663
+ "You need prefix, suffix, or password toggle support"
6664
+ ],
6665
+ props: [
6666
+ { name: "label", type: "ReactNode", description: "Field label rendered above the control." },
6667
+ { name: "helperText", type: "ReactNode", description: "Supplemental guidance shown below." },
6668
+ { name: "errorMessage", type: "ReactNode", description: "Validation message shown below in error state." },
6669
+ { name: "prefix", type: "ReactNode", description: "Visual prefix inside the field." },
6670
+ { name: "suffix", type: "ReactNode", description: "Visual suffix inside the field." }
6671
+ ],
6672
+ example: "<Input label='Email' type='email' placeholder='you@example.com' />",
6673
+ related: ["Textarea", "NumericInput", "Field"]
6674
+ },
6675
+ {
6676
+ name: "Multiline text input",
6677
+ importName: "Textarea",
6678
+ purpose: "Capture longer free-form content.",
6679
+ useWhen: [
6680
+ "The user needs multiple lines of text",
6681
+ "A description, note, or comment field is needed"
6682
+ ],
6683
+ props: [
6684
+ { name: "label", type: "ReactNode", description: "Field label rendered above the textarea." },
6685
+ { name: "rows", type: "number", description: "Controls initial textarea height." },
6686
+ { name: "helperText", type: "ReactNode", description: "Supplemental guidance shown below." },
6687
+ { name: "errorMessage", type: "ReactNode", description: "Validation message shown below in error state." }
6688
+ ],
6689
+ example: "<Textarea label='Description' rows={5} placeholder='Write the details...' />",
6690
+ related: ["Input", "Field"]
6691
+ },
6692
+ {
6693
+ name: "Single select",
6694
+ importName: "Select",
6695
+ purpose: "Pick one value from a small fixed option set.",
6696
+ useWhen: [
6697
+ "Fewer options and no search is required",
6698
+ "A simple dropdown is enough"
6699
+ ],
6700
+ props: [
6701
+ { name: "options", type: "SelectOption[]", required: true, description: "List of selectable options." },
6702
+ { name: "label", type: "ReactNode", description: "Field label rendered above the trigger." },
6703
+ { name: "placeholder", type: "string", description: "Placeholder shown when no value is selected." },
6704
+ { name: "onChange", type: "(value) => void", description: "Returns the original option value type." }
6705
+ ],
6706
+ example: "<Select label='Plan' options={[{ label: 'Starter', value: 'starter' }]} />",
6707
+ related: ["SearchableSelect", "Combobox"]
6708
+ },
6709
+ {
6710
+ name: "Searchable local select",
6711
+ importName: "SearchableSelect",
6712
+ purpose: "Pick one value from a larger in-memory list with search.",
6713
+ useWhen: [
6714
+ "More than a handful of options exist",
6715
+ "Local filtering is enough"
6716
+ ],
6717
+ props: [
6718
+ { name: "options", type: "SearchableSelectOption[]", required: true, description: "List of selectable options." },
6719
+ { name: "searchPlaceholder", type: "string", description: "Placeholder inside the search field." },
6720
+ { name: "onSearch", type: "(query) => void", description: "Receives the local search query." }
6721
+ ],
6722
+ example: "<SearchableSelect label='Country' searchPlaceholder='Search country' options={countries} />",
6723
+ related: ["Select", "Combobox", "AsyncCombobox"]
6724
+ },
6725
+ {
6726
+ name: "Type and pick",
6727
+ importName: "Combobox",
6728
+ purpose: "Let the user type and choose from a filtered list.",
6729
+ useWhen: [
6730
+ "A command-palette-like input is needed",
6731
+ "The typed text should stay visible in the input"
6732
+ ],
6733
+ props: [
6734
+ { name: "options", type: "ComboboxOption[]", required: true, description: "List of options to filter." },
6735
+ { name: "value", type: "string | number", description: "Selected value." },
6736
+ { name: "onChange", type: "(value) => void", description: "Selected value callback." }
6737
+ ],
6738
+ example: "<Combobox label='Assignee' options={users} value={assigneeId} onChange={setAssigneeId} />",
6739
+ related: ["SearchableSelect", "AsyncCombobox"]
6740
+ },
6741
+ {
6742
+ name: "Remote search combobox",
6743
+ importName: "AsyncCombobox",
6744
+ purpose: "Search and pick from server-backed data.",
6745
+ useWhen: [
6746
+ "Options are loaded from an API",
6747
+ "Infinite scroll or async fetching is needed"
6748
+ ],
6749
+ props: [
6750
+ { name: "options", type: "ComboboxOption[]", required: true, description: "Currently loaded options." },
6751
+ { name: "loading", type: "boolean", description: "Shows async loading state." },
6752
+ { name: "onSearch", type: "(query) => void", required: true, description: "Triggers remote search." },
6753
+ { name: "onLoadMore", type: "() => void", description: "Loads more options when scrolling near the end." }
6754
+ ],
6755
+ example: "<AsyncCombobox label='User' options={options} loading={loading} onSearch={searchUsers} />",
6756
+ related: ["Combobox", "SearchableSelect"]
6757
+ },
6758
+ {
6759
+ name: "Multiple selection",
6760
+ importName: "MultiSelect",
6761
+ purpose: "Choose many values from a searchable list.",
6762
+ useWhen: [
6763
+ "The user can pick multiple tags, users, or filters"
6764
+ ],
6765
+ props: [
6766
+ { name: "options", type: "MultiSelectOption[]", required: true, description: "List of selectable options." },
6767
+ { name: "value", type: "Array<string | number>", description: "Selected values." },
6768
+ { name: "onChange", type: "(values) => void", description: "Selected values callback." }
6769
+ ],
6770
+ example: "<MultiSelect label='Tags' options={tagOptions} value={tags} onChange={setTags} />",
6771
+ related: ["Select", "SearchableSelect"]
6772
+ },
6773
+ {
6774
+ name: "Structured field wrapper",
6775
+ importName: "Field",
6776
+ purpose: "Add a shared label/helper/error wrapper around custom content.",
6777
+ useWhen: [
6778
+ "Wrapping a custom control that does not expose label props",
6779
+ "Grouping multiple controls under one heading"
6780
+ ],
6781
+ avoidWhen: [
6782
+ "A built-in form control already renders its own label and helper text"
6783
+ ],
6784
+ props: [
6785
+ { name: "label", type: "ReactNode", description: "Field label rendered above children." },
6786
+ { name: "helperText", type: "ReactNode", description: "Helper text below children." },
6787
+ { name: "errorMessage", type: "ReactNode", description: "Error text below children." },
6788
+ { name: "htmlFor", type: "string", description: "Associates the label with the wrapped control id." }
6789
+ ],
6790
+ example: "<Field label='Schedule' htmlFor='range'><DateRangePicker id='range' /></Field>",
6791
+ related: ["Input", "Textarea", "Select"]
6792
+ },
6793
+ {
6794
+ name: "Data table",
6795
+ importName: "DataTable",
6796
+ purpose: "Render sortable tabular data with optional selection, actions, loading, and pagination.",
6797
+ useWhen: [
6798
+ "Displaying records in rows and columns",
6799
+ "Sort, pagination, selection, or row actions are required"
6800
+ ],
6801
+ props: [
6802
+ { name: "columns", type: "DataTableColumn<T>[]", required: true, description: "Column definitions." },
6803
+ { name: "data", type: "T[]", required: true, description: "Rows to render." },
6804
+ { name: "rowKey", type: "keyof T | ((record: T) => string | number)", required: true, description: "Stable key for each row." },
6805
+ { name: "pagination", type: "DataTablePagination", description: "Enables pagination controls." },
6806
+ { name: "sortMode", type: "'client' | 'server'", description: "Choose client or backend sorting." }
6807
+ ],
6808
+ example: "<DataTable rowKey='id' columns={columns} data={rows} pagination={pagination} />",
6809
+ related: ["Card", "Pagination", "Loading"]
6810
+ },
6811
+ {
6812
+ name: "Status message",
6813
+ importName: "Alert",
6814
+ purpose: "Communicate neutral, success, warning, or danger states.",
6815
+ useWhen: [
6816
+ "You need a visible status or validation banner"
6817
+ ],
6818
+ props: [
6819
+ { name: "tone", type: "'neutral' | 'info' | 'success' | 'warning' | 'danger'", description: "Semantic tone mapping." },
6820
+ { name: "title", type: "ReactNode", description: "Alert headline." },
6821
+ { name: "description", type: "ReactNode", description: "Supporting message." }
6822
+ ],
6823
+ example: "<Alert tone='warning' title='Missing information' description='Please fill all required fields.' />",
6824
+ related: ["Loading", "Card"]
6825
+ },
6826
+ {
6827
+ name: "Layout section",
6828
+ importName: "Card",
6829
+ purpose: "Wrap a coherent chunk of UI in a bordered surface.",
6830
+ useWhen: [
6831
+ "Building forms, dashboards, settings sections, or summary panels"
6832
+ ],
6833
+ props: [
6834
+ { name: "className", type: "string", description: "Adds layout-specific spacing or width." }
6835
+ ],
6836
+ example: "<Card><CardHeader><CardTitle>Account</CardTitle></CardHeader><CardContent>...</CardContent></Card>",
6837
+ related: ["CardHeader", "CardTitle", "CardContent", "CardFooter"]
6838
+ }
6839
+ ]
6840
+ };
6841
+
6842
+ // src/theme-contract.ts
6843
+ var uiThemeContract = {
6844
+ packageName: "@lucasvu/scope-ui",
6845
+ importOrder: [
6846
+ "import '@lucasvu/scope-ui/styles.css'",
6847
+ "import './styles/ui-theme.css'"
6848
+ ],
6849
+ selectors: {
6850
+ light: [":root", "[data-ui-theme='light']"],
6851
+ dark: [".dark", "[data-ui-theme='dark']"]
6852
+ },
6853
+ overrideFile: "src/styles/ui-theme.css",
6854
+ rules: [
6855
+ "Import the package stylesheet before your project theme override stylesheet.",
6856
+ "Override tokens in one shared theme file instead of scattering colors across components.",
6857
+ "Use :root for the default light theme and .dark or [data-ui-theme='dark'] for dark theme.",
6858
+ "Only override tokens declared here. Do not patch component internals unless you are extending the library.",
6859
+ "For AI-generated screens, choose one theme source of truth and keep component code token-driven."
6860
+ ],
6861
+ tokens: [
6862
+ {
6863
+ name: "--tw-background",
6864
+ description: "Base app background in HSL triplet format.",
6865
+ defaultLight: "0 0% 100%",
6866
+ defaultDark: "222.2 84% 4.9%",
6867
+ usedBy: ["Input", "Select", "Card", "Tabs", "global surface"]
6868
+ },
6869
+ {
6870
+ name: "--tw-foreground",
6871
+ description: "Primary text color in HSL triplet format.",
6872
+ defaultLight: "222.2 47.4% 11.2%",
6873
+ defaultDark: "210 40% 98%",
6874
+ usedBy: ["Button", "Input", "Card", "Typography"]
6875
+ },
6876
+ {
6877
+ name: "--tw-primary",
6878
+ description: "Primary brand color in HSL triplet format.",
6879
+ defaultLight: "221.2 83.2% 53.3%",
6880
+ defaultDark: "217.2 91.2% 59.8%",
6881
+ usedBy: ["Button", "focus rings", "brand emphasis"]
6882
+ },
6883
+ {
6884
+ name: "--tw-accent",
6885
+ description: "Accent color in HSL triplet format.",
6886
+ defaultLight: "199 89% 48%",
6887
+ defaultDark: "199 89% 48%",
6888
+ usedBy: ["Tabs", "checkbox accent", "highlight states"]
6889
+ },
6890
+ {
6891
+ name: "--tw-success",
6892
+ description: "Success state color in HSL triplet format.",
6893
+ defaultLight: "142.1 76.2% 36.3%",
6894
+ defaultDark: "142.1 70.6% 45.3%",
6895
+ usedBy: ["Alert", "confirm buttons", "status text"]
6896
+ },
6897
+ {
6898
+ name: "--tw-destructive",
6899
+ description: "Danger state color in HSL triplet format.",
6900
+ defaultLight: "0 84.2% 60.2%",
6901
+ defaultDark: "0 62.8% 30.6%",
6902
+ usedBy: ["Alert", "destructive buttons", "error states"]
6903
+ },
6904
+ {
6905
+ name: "--tw-border",
6906
+ description: "Border color in HSL triplet format.",
6907
+ defaultLight: "214.3 31.8% 91.4%",
6908
+ defaultDark: "217.2 32.6% 17.5%",
6909
+ usedBy: ["Input", "Select", "Card", "DataTable"]
6910
+ },
6911
+ {
6912
+ name: "--surface",
6913
+ description: "Default surface background as a CSS color.",
6914
+ defaultLight: "rgba(255, 255, 255, 0.92)",
6915
+ defaultDark: "rgba(15, 23, 42, 0.78)",
6916
+ usedBy: ["Tabs", "Pagination", "glass surfaces"]
6917
+ },
6918
+ {
6919
+ name: "--surface-strong",
6920
+ description: "Stronger elevated surface as a CSS color.",
6921
+ defaultLight: "rgba(241, 245, 249, 0.96)",
6922
+ defaultDark: "rgba(30, 41, 59, 0.92)",
6923
+ usedBy: ["Pagination hover", "raised surfaces"]
6924
+ },
6925
+ {
6926
+ name: "--grey",
6927
+ description: "Neutral table/header background as a CSS color.",
6928
+ defaultLight: "rgba(248, 250, 252, 0.96)",
6929
+ defaultDark: "rgba(30, 41, 59, 0.88)",
6930
+ usedBy: ["DataTable header"]
6931
+ },
6932
+ {
6933
+ name: "--grey-strong",
6934
+ description: "Hover background for neutral rows as a CSS color.",
6935
+ defaultLight: "rgba(241, 245, 249, 0.98)",
6936
+ defaultDark: "rgba(51, 65, 85, 0.92)",
6937
+ usedBy: ["DataTable row hover"]
6938
+ },
6939
+ {
6940
+ name: "--text",
6941
+ description: "Generic text color alias as a CSS color.",
6942
+ defaultLight: "hsl(var(--tw-foreground))",
6943
+ defaultDark: "hsl(var(--tw-foreground))",
6944
+ usedBy: ["Pagination", "legacy utility surfaces"]
6945
+ },
6946
+ {
6947
+ name: "--muted",
6948
+ description: "Generic muted text color alias as a CSS color.",
6949
+ defaultLight: "hsl(var(--tw-muted-foreground))",
6950
+ defaultDark: "hsl(var(--tw-muted-foreground))",
6951
+ usedBy: ["Pagination", "DataTable sort icon", "helper text"]
6952
+ },
6953
+ {
6954
+ name: "--accent",
6955
+ description: "Generic accent color alias as a CSS color.",
6956
+ defaultLight: "hsl(var(--tw-accent))",
6957
+ defaultDark: "hsl(var(--tw-accent))",
6958
+ usedBy: ["DataTable checkbox accent", "focus accents"]
6959
+ },
6960
+ {
6961
+ name: "--primary-grad-from",
6962
+ description: "Gradient start color in HSL triplet format.",
6963
+ defaultLight: "199 89% 48%",
6964
+ defaultDark: "198.6 88.7% 48.4%",
6965
+ usedBy: ["Button variant create"]
6966
+ },
6967
+ {
6968
+ name: "--primary-grad-to",
6969
+ description: "Gradient end color in HSL triplet format.",
6970
+ defaultLight: "221.2 83.2% 53.3%",
6971
+ defaultDark: "221.2 83.2% 53.3%",
6972
+ usedBy: ["Button variant create"]
6973
+ }
6974
+ ],
6975
+ exampleCss: `:root {
6976
+ --tw-primary: 12 88% 56%;
6977
+ --tw-accent: 24 95% 52%;
6978
+ --primary-grad-from: 24 95% 52%;
6979
+ --primary-grad-to: 12 88% 56%;
6980
+ --surface: rgba(255, 248, 240, 0.92);
6981
+ }
6982
+
6983
+ .dark {
6984
+ --tw-primary: 18 100% 62%;
6985
+ --tw-accent: 35 100% 58%;
6986
+ --surface: rgba(24, 24, 27, 0.82);
6987
+ }`
6988
+ };
6989
+ var uiProjectAiRules = [
6990
+ "Use @lucasvu/scope-ui as the default UI library.",
6991
+ "Import @lucasvu/scope-ui/styles.css once at the app entry.",
6992
+ "Import the project override theme file after the package stylesheet.",
6993
+ "Read uiAiManifest to choose the correct component by intent before coding.",
6994
+ "Read uiThemeContract before changing colors, shadows, or theme behavior.",
6995
+ "Prefer root exports and avoid MainFe unless the task explicitly targets a legacy screen."
6996
+ ];
6997
+
6998
+ export { Alert, ArgonSidebar, AsyncCombobox, Badge, Breadcrumb, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Combobox, FormControl as Control, DataTable, FormDescription as Description, FormField as Field, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Input, FormItem as Item, FormLabel as Label, LineClampTooltip, Loading, main_fe_exports as MainFe, FormMessage as Message, MultiSelect, NumericInput, OverflowTooltip, PageTitle, Pagination, SearchableSelect, SectionTitle, Select, Sidebar, SidebarItem, Stat, Table, TableBody, TableCell, TableHeader, TableRow, Tabs, Textarea, Tooltip, TruncatedText, cn, defaultPermissionChecker, filterSidebarItems, hasActiveDescendant, uiAiManifest, uiProjectAiRules, uiThemeContract };