@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.cjs CHANGED
@@ -457,6 +457,7 @@ var Button = react.forwardRef(
457
457
  disabled,
458
458
  startIcon,
459
459
  endIcon,
460
+ block = false,
460
461
  className,
461
462
  style,
462
463
  children,
@@ -469,14 +470,14 @@ var Button = react.forwardRef(
469
470
  const describedBy = [helperId, errorId].filter(Boolean).join(" ") || void 0;
470
471
  const content = children ?? label;
471
472
  const isDisabled = disabled || loading;
472
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", style, children: [
473
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1", block && "w-full"), style, children: [
473
474
  /* @__PURE__ */ jsxRuntime.jsxs(
474
475
  "button",
475
476
  {
476
477
  ref,
477
478
  id: buttonId,
478
479
  type: type ?? "button",
479
- className: cn(buttonVariants({ variant, size, className })),
480
+ className: cn(buttonVariants({ variant, size, className }), block && "w-full"),
480
481
  disabled: isDisabled,
481
482
  "aria-describedby": describedBy,
482
483
  "aria-busy": loading || void 0,
@@ -897,6 +898,94 @@ var NumericInput = react.forwardRef(
897
898
  }
898
899
  );
899
900
  NumericInput.displayName = "NumericInput";
901
+ var textareaVariants = classVarianceAuthority.cva(
902
+ "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",
903
+ {
904
+ variants: {
905
+ variant: {
906
+ default: "border-input bg-background text-foreground hover:border-border",
907
+ ghost: "border-transparent bg-transparent text-foreground focus-visible:border-border/60",
908
+ outline: "border border-border bg-transparent text-foreground"
909
+ },
910
+ size: {
911
+ sm: "min-h-[88px] text-sm",
912
+ md: "min-h-[104px] text-sm",
913
+ lg: "min-h-[120px] text-base"
914
+ }
915
+ },
916
+ defaultVariants: {
917
+ variant: "default",
918
+ size: "md"
919
+ }
920
+ }
921
+ );
922
+ var Textarea = react.forwardRef(
923
+ ({
924
+ variant = "default",
925
+ size = "md",
926
+ label,
927
+ helperText,
928
+ errorMessage,
929
+ loading,
930
+ disabled,
931
+ className,
932
+ style,
933
+ textareaClassName,
934
+ id,
935
+ onChange,
936
+ onValueChange,
937
+ suffix,
938
+ rows,
939
+ ...rest
940
+ }, ref) => {
941
+ const generatedId = react.useId();
942
+ const textareaId = id ?? generatedId;
943
+ const helperId = helperText ? `${textareaId}-helper` : void 0;
944
+ const errorId = errorMessage ? `${textareaId}-error` : void 0;
945
+ const hasRightAccessory = Boolean(suffix) || Boolean(loading);
946
+ return /* @__PURE__ */ jsxRuntime.jsx(
947
+ FieldWrapper,
948
+ {
949
+ label,
950
+ helperText,
951
+ errorMessage,
952
+ helperId,
953
+ errorId,
954
+ htmlFor: textareaId,
955
+ className,
956
+ style,
957
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
958
+ /* @__PURE__ */ jsxRuntime.jsx(
959
+ "textarea",
960
+ {
961
+ id: textareaId,
962
+ ref,
963
+ rows: rows ?? 4,
964
+ className: cn(
965
+ textareaVariants({ variant, size }),
966
+ hasRightAccessory && "pr-10",
967
+ textareaClassName
968
+ ),
969
+ disabled: disabled || loading,
970
+ "aria-invalid": Boolean(errorMessage),
971
+ "aria-describedby": [helperId, errorId].filter(Boolean).join(" ") || void 0,
972
+ onChange: (event) => {
973
+ onChange?.(event);
974
+ onValueChange?.(event.target.value);
975
+ },
976
+ ...rest
977
+ }
978
+ ),
979
+ hasRightAccessory ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pointer-events-none absolute right-3 top-3 flex items-center gap-2 text-muted-foreground", children: [
980
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, { size: "xs" }) : null,
981
+ suffix ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: suffix }) : null
982
+ ] }) : null
983
+ ] })
984
+ }
985
+ );
986
+ }
987
+ );
988
+ Textarea.displayName = "Textarea";
900
989
  function Card({ className, ...props }) {
901
990
  return /* @__PURE__ */ jsxRuntime.jsx(
902
991
  "div",
@@ -1802,9 +1891,18 @@ function CheckMark() {
1802
1891
  function Form({ className, ...props }) {
1803
1892
  return /* @__PURE__ */ jsxRuntime.jsx("form", { className: cn("space-y-6", className), ...props });
1804
1893
  }
1805
- var FormField = react.forwardRef(({ className, ...props }, ref) => {
1806
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("grid gap-2", className), ...props });
1807
- });
1894
+ var FormField = react.forwardRef(
1895
+ ({ className, label, helperText, errorMessage, required, htmlFor, children, ...props }, ref) => {
1896
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("grid gap-2", className), ...props, children: [
1897
+ label ? /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-semibold leading-none text-foreground", children: [
1898
+ label,
1899
+ required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-destructive", children: "*" }) : null
1900
+ ] }) : null,
1901
+ children,
1902
+ errorMessage ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: errorMessage }) : helperText ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: helperText }) : null
1903
+ ] });
1904
+ }
1905
+ );
1808
1906
  FormField.displayName = "FormField";
1809
1907
  var FormItem = react.forwardRef(({ className, ...props }, ref) => {
1810
1908
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col space-y-2", className), ...props });
@@ -2031,6 +2129,13 @@ var SearchableSelect = react.forwardRef(
2031
2129
  return candidate.toLowerCase().includes(normalized);
2032
2130
  });
2033
2131
  }, [options, searchTerm]);
2132
+ const normalizeValue = react.useCallback(
2133
+ (raw) => {
2134
+ const match = options.find((option) => String(option.value) === raw);
2135
+ return match ? match.value : raw;
2136
+ },
2137
+ [options]
2138
+ );
2034
2139
  const handleOpenChange = react.useCallback(
2035
2140
  (next) => {
2036
2141
  setIsOpen(next);
@@ -2074,7 +2179,7 @@ var SearchableSelect = react.forwardRef(
2074
2179
  {
2075
2180
  value: value !== void 0 ? String(value) : void 0,
2076
2181
  defaultValue: defaultValue !== void 0 ? String(defaultValue) : void 0,
2077
- onValueChange: (next) => onChange?.(next),
2182
+ onValueChange: (next) => onChange?.(normalizeValue(next)),
2078
2183
  disabled: disabled || loading,
2079
2184
  onOpenChange: handleOpenChange,
2080
2185
  ...props,
@@ -6535,6 +6640,383 @@ function PageTitle2({
6535
6640
  );
6536
6641
  }
6537
6642
 
6643
+ // src/ai-manifest.ts
6644
+ var uiAiManifest = {
6645
+ packageName: "@lucasvu/scope-ui",
6646
+ styleImport: "@lucasvu/scope-ui/styles.css",
6647
+ rules: [
6648
+ "Import the stylesheet once at the app entry before rendering any component.",
6649
+ "Prefer the canonical component for each intent instead of mixing legacy MainFe components.",
6650
+ "Use Input/Textarea/Select label props directly for simple fields; use Field only to wrap custom controls or grouped content.",
6651
+ "Use Select for small fixed option lists, SearchableSelect for larger local lists, Combobox for type-and-pick flows, and AsyncCombobox for remote search.",
6652
+ 'Always provide a stable rowKey to DataTable and use sortMode="server" when sorting happens on the backend.',
6653
+ "Prefer Card as the outer layout section and keep alerts, stats, and tables inside CardContent when building dashboards or forms.",
6654
+ "Do not import MainFe components unless the target explicitly asks for legacy main-fe styling."
6655
+ ],
6656
+ components: [
6657
+ {
6658
+ name: "Primary action",
6659
+ importName: "Button",
6660
+ purpose: "Render the main clickable action.",
6661
+ useWhen: [
6662
+ "Submitting a form",
6663
+ "Triggering create/save/confirm flows",
6664
+ "Need loading or block width support"
6665
+ ],
6666
+ avoidWhen: [
6667
+ "Pure navigation text links without button semantics"
6668
+ ],
6669
+ props: [
6670
+ { name: "variant", type: "'default' | 'secondary' | 'ghost' | 'outline' | 'destructive' | 'link' | 'confirm' | 'create'", description: "Chooses the visual emphasis." },
6671
+ { name: "size", type: "'sm' | 'md' | 'lg' | 'icon'", description: "Chooses the button size." },
6672
+ { name: "block", type: "boolean", description: "Expands the button to full width." },
6673
+ { name: "loading", type: "boolean", description: "Shows a spinner and disables interaction." }
6674
+ ],
6675
+ example: "<Button variant='create' block>Save changes</Button>",
6676
+ related: ["Alert", "Card"]
6677
+ },
6678
+ {
6679
+ name: "Single-line text input",
6680
+ importName: "Input",
6681
+ purpose: "Capture short text, email, password, number-like strings, or search text.",
6682
+ useWhen: [
6683
+ "A single text value is needed",
6684
+ "You need label/helper/error handling built in",
6685
+ "You need prefix, suffix, or password toggle support"
6686
+ ],
6687
+ props: [
6688
+ { name: "label", type: "ReactNode", description: "Field label rendered above the control." },
6689
+ { name: "helperText", type: "ReactNode", description: "Supplemental guidance shown below." },
6690
+ { name: "errorMessage", type: "ReactNode", description: "Validation message shown below in error state." },
6691
+ { name: "prefix", type: "ReactNode", description: "Visual prefix inside the field." },
6692
+ { name: "suffix", type: "ReactNode", description: "Visual suffix inside the field." }
6693
+ ],
6694
+ example: "<Input label='Email' type='email' placeholder='you@example.com' />",
6695
+ related: ["Textarea", "NumericInput", "Field"]
6696
+ },
6697
+ {
6698
+ name: "Multiline text input",
6699
+ importName: "Textarea",
6700
+ purpose: "Capture longer free-form content.",
6701
+ useWhen: [
6702
+ "The user needs multiple lines of text",
6703
+ "A description, note, or comment field is needed"
6704
+ ],
6705
+ props: [
6706
+ { name: "label", type: "ReactNode", description: "Field label rendered above the textarea." },
6707
+ { name: "rows", type: "number", description: "Controls initial textarea height." },
6708
+ { name: "helperText", type: "ReactNode", description: "Supplemental guidance shown below." },
6709
+ { name: "errorMessage", type: "ReactNode", description: "Validation message shown below in error state." }
6710
+ ],
6711
+ example: "<Textarea label='Description' rows={5} placeholder='Write the details...' />",
6712
+ related: ["Input", "Field"]
6713
+ },
6714
+ {
6715
+ name: "Single select",
6716
+ importName: "Select",
6717
+ purpose: "Pick one value from a small fixed option set.",
6718
+ useWhen: [
6719
+ "Fewer options and no search is required",
6720
+ "A simple dropdown is enough"
6721
+ ],
6722
+ props: [
6723
+ { name: "options", type: "SelectOption[]", required: true, description: "List of selectable options." },
6724
+ { name: "label", type: "ReactNode", description: "Field label rendered above the trigger." },
6725
+ { name: "placeholder", type: "string", description: "Placeholder shown when no value is selected." },
6726
+ { name: "onChange", type: "(value) => void", description: "Returns the original option value type." }
6727
+ ],
6728
+ example: "<Select label='Plan' options={[{ label: 'Starter', value: 'starter' }]} />",
6729
+ related: ["SearchableSelect", "Combobox"]
6730
+ },
6731
+ {
6732
+ name: "Searchable local select",
6733
+ importName: "SearchableSelect",
6734
+ purpose: "Pick one value from a larger in-memory list with search.",
6735
+ useWhen: [
6736
+ "More than a handful of options exist",
6737
+ "Local filtering is enough"
6738
+ ],
6739
+ props: [
6740
+ { name: "options", type: "SearchableSelectOption[]", required: true, description: "List of selectable options." },
6741
+ { name: "searchPlaceholder", type: "string", description: "Placeholder inside the search field." },
6742
+ { name: "onSearch", type: "(query) => void", description: "Receives the local search query." }
6743
+ ],
6744
+ example: "<SearchableSelect label='Country' searchPlaceholder='Search country' options={countries} />",
6745
+ related: ["Select", "Combobox", "AsyncCombobox"]
6746
+ },
6747
+ {
6748
+ name: "Type and pick",
6749
+ importName: "Combobox",
6750
+ purpose: "Let the user type and choose from a filtered list.",
6751
+ useWhen: [
6752
+ "A command-palette-like input is needed",
6753
+ "The typed text should stay visible in the input"
6754
+ ],
6755
+ props: [
6756
+ { name: "options", type: "ComboboxOption[]", required: true, description: "List of options to filter." },
6757
+ { name: "value", type: "string | number", description: "Selected value." },
6758
+ { name: "onChange", type: "(value) => void", description: "Selected value callback." }
6759
+ ],
6760
+ example: "<Combobox label='Assignee' options={users} value={assigneeId} onChange={setAssigneeId} />",
6761
+ related: ["SearchableSelect", "AsyncCombobox"]
6762
+ },
6763
+ {
6764
+ name: "Remote search combobox",
6765
+ importName: "AsyncCombobox",
6766
+ purpose: "Search and pick from server-backed data.",
6767
+ useWhen: [
6768
+ "Options are loaded from an API",
6769
+ "Infinite scroll or async fetching is needed"
6770
+ ],
6771
+ props: [
6772
+ { name: "options", type: "ComboboxOption[]", required: true, description: "Currently loaded options." },
6773
+ { name: "loading", type: "boolean", description: "Shows async loading state." },
6774
+ { name: "onSearch", type: "(query) => void", required: true, description: "Triggers remote search." },
6775
+ { name: "onLoadMore", type: "() => void", description: "Loads more options when scrolling near the end." }
6776
+ ],
6777
+ example: "<AsyncCombobox label='User' options={options} loading={loading} onSearch={searchUsers} />",
6778
+ related: ["Combobox", "SearchableSelect"]
6779
+ },
6780
+ {
6781
+ name: "Multiple selection",
6782
+ importName: "MultiSelect",
6783
+ purpose: "Choose many values from a searchable list.",
6784
+ useWhen: [
6785
+ "The user can pick multiple tags, users, or filters"
6786
+ ],
6787
+ props: [
6788
+ { name: "options", type: "MultiSelectOption[]", required: true, description: "List of selectable options." },
6789
+ { name: "value", type: "Array<string | number>", description: "Selected values." },
6790
+ { name: "onChange", type: "(values) => void", description: "Selected values callback." }
6791
+ ],
6792
+ example: "<MultiSelect label='Tags' options={tagOptions} value={tags} onChange={setTags} />",
6793
+ related: ["Select", "SearchableSelect"]
6794
+ },
6795
+ {
6796
+ name: "Structured field wrapper",
6797
+ importName: "Field",
6798
+ purpose: "Add a shared label/helper/error wrapper around custom content.",
6799
+ useWhen: [
6800
+ "Wrapping a custom control that does not expose label props",
6801
+ "Grouping multiple controls under one heading"
6802
+ ],
6803
+ avoidWhen: [
6804
+ "A built-in form control already renders its own label and helper text"
6805
+ ],
6806
+ props: [
6807
+ { name: "label", type: "ReactNode", description: "Field label rendered above children." },
6808
+ { name: "helperText", type: "ReactNode", description: "Helper text below children." },
6809
+ { name: "errorMessage", type: "ReactNode", description: "Error text below children." },
6810
+ { name: "htmlFor", type: "string", description: "Associates the label with the wrapped control id." }
6811
+ ],
6812
+ example: "<Field label='Schedule' htmlFor='range'><DateRangePicker id='range' /></Field>",
6813
+ related: ["Input", "Textarea", "Select"]
6814
+ },
6815
+ {
6816
+ name: "Data table",
6817
+ importName: "DataTable",
6818
+ purpose: "Render sortable tabular data with optional selection, actions, loading, and pagination.",
6819
+ useWhen: [
6820
+ "Displaying records in rows and columns",
6821
+ "Sort, pagination, selection, or row actions are required"
6822
+ ],
6823
+ props: [
6824
+ { name: "columns", type: "DataTableColumn<T>[]", required: true, description: "Column definitions." },
6825
+ { name: "data", type: "T[]", required: true, description: "Rows to render." },
6826
+ { name: "rowKey", type: "keyof T | ((record: T) => string | number)", required: true, description: "Stable key for each row." },
6827
+ { name: "pagination", type: "DataTablePagination", description: "Enables pagination controls." },
6828
+ { name: "sortMode", type: "'client' | 'server'", description: "Choose client or backend sorting." }
6829
+ ],
6830
+ example: "<DataTable rowKey='id' columns={columns} data={rows} pagination={pagination} />",
6831
+ related: ["Card", "Pagination", "Loading"]
6832
+ },
6833
+ {
6834
+ name: "Status message",
6835
+ importName: "Alert",
6836
+ purpose: "Communicate neutral, success, warning, or danger states.",
6837
+ useWhen: [
6838
+ "You need a visible status or validation banner"
6839
+ ],
6840
+ props: [
6841
+ { name: "tone", type: "'neutral' | 'info' | 'success' | 'warning' | 'danger'", description: "Semantic tone mapping." },
6842
+ { name: "title", type: "ReactNode", description: "Alert headline." },
6843
+ { name: "description", type: "ReactNode", description: "Supporting message." }
6844
+ ],
6845
+ example: "<Alert tone='warning' title='Missing information' description='Please fill all required fields.' />",
6846
+ related: ["Loading", "Card"]
6847
+ },
6848
+ {
6849
+ name: "Layout section",
6850
+ importName: "Card",
6851
+ purpose: "Wrap a coherent chunk of UI in a bordered surface.",
6852
+ useWhen: [
6853
+ "Building forms, dashboards, settings sections, or summary panels"
6854
+ ],
6855
+ props: [
6856
+ { name: "className", type: "string", description: "Adds layout-specific spacing or width." }
6857
+ ],
6858
+ example: "<Card><CardHeader><CardTitle>Account</CardTitle></CardHeader><CardContent>...</CardContent></Card>",
6859
+ related: ["CardHeader", "CardTitle", "CardContent", "CardFooter"]
6860
+ }
6861
+ ]
6862
+ };
6863
+
6864
+ // src/theme-contract.ts
6865
+ var uiThemeContract = {
6866
+ packageName: "@lucasvu/scope-ui",
6867
+ importOrder: [
6868
+ "import '@lucasvu/scope-ui/styles.css'",
6869
+ "import './styles/ui-theme.css'"
6870
+ ],
6871
+ selectors: {
6872
+ light: [":root", "[data-ui-theme='light']"],
6873
+ dark: [".dark", "[data-ui-theme='dark']"]
6874
+ },
6875
+ overrideFile: "src/styles/ui-theme.css",
6876
+ rules: [
6877
+ "Import the package stylesheet before your project theme override stylesheet.",
6878
+ "Override tokens in one shared theme file instead of scattering colors across components.",
6879
+ "Use :root for the default light theme and .dark or [data-ui-theme='dark'] for dark theme.",
6880
+ "Only override tokens declared here. Do not patch component internals unless you are extending the library.",
6881
+ "For AI-generated screens, choose one theme source of truth and keep component code token-driven."
6882
+ ],
6883
+ tokens: [
6884
+ {
6885
+ name: "--tw-background",
6886
+ description: "Base app background in HSL triplet format.",
6887
+ defaultLight: "0 0% 100%",
6888
+ defaultDark: "222.2 84% 4.9%",
6889
+ usedBy: ["Input", "Select", "Card", "Tabs", "global surface"]
6890
+ },
6891
+ {
6892
+ name: "--tw-foreground",
6893
+ description: "Primary text color in HSL triplet format.",
6894
+ defaultLight: "222.2 47.4% 11.2%",
6895
+ defaultDark: "210 40% 98%",
6896
+ usedBy: ["Button", "Input", "Card", "Typography"]
6897
+ },
6898
+ {
6899
+ name: "--tw-primary",
6900
+ description: "Primary brand color in HSL triplet format.",
6901
+ defaultLight: "221.2 83.2% 53.3%",
6902
+ defaultDark: "217.2 91.2% 59.8%",
6903
+ usedBy: ["Button", "focus rings", "brand emphasis"]
6904
+ },
6905
+ {
6906
+ name: "--tw-accent",
6907
+ description: "Accent color in HSL triplet format.",
6908
+ defaultLight: "199 89% 48%",
6909
+ defaultDark: "199 89% 48%",
6910
+ usedBy: ["Tabs", "checkbox accent", "highlight states"]
6911
+ },
6912
+ {
6913
+ name: "--tw-success",
6914
+ description: "Success state color in HSL triplet format.",
6915
+ defaultLight: "142.1 76.2% 36.3%",
6916
+ defaultDark: "142.1 70.6% 45.3%",
6917
+ usedBy: ["Alert", "confirm buttons", "status text"]
6918
+ },
6919
+ {
6920
+ name: "--tw-destructive",
6921
+ description: "Danger state color in HSL triplet format.",
6922
+ defaultLight: "0 84.2% 60.2%",
6923
+ defaultDark: "0 62.8% 30.6%",
6924
+ usedBy: ["Alert", "destructive buttons", "error states"]
6925
+ },
6926
+ {
6927
+ name: "--tw-border",
6928
+ description: "Border color in HSL triplet format.",
6929
+ defaultLight: "214.3 31.8% 91.4%",
6930
+ defaultDark: "217.2 32.6% 17.5%",
6931
+ usedBy: ["Input", "Select", "Card", "DataTable"]
6932
+ },
6933
+ {
6934
+ name: "--surface",
6935
+ description: "Default surface background as a CSS color.",
6936
+ defaultLight: "rgba(255, 255, 255, 0.92)",
6937
+ defaultDark: "rgba(15, 23, 42, 0.78)",
6938
+ usedBy: ["Tabs", "Pagination", "glass surfaces"]
6939
+ },
6940
+ {
6941
+ name: "--surface-strong",
6942
+ description: "Stronger elevated surface as a CSS color.",
6943
+ defaultLight: "rgba(241, 245, 249, 0.96)",
6944
+ defaultDark: "rgba(30, 41, 59, 0.92)",
6945
+ usedBy: ["Pagination hover", "raised surfaces"]
6946
+ },
6947
+ {
6948
+ name: "--grey",
6949
+ description: "Neutral table/header background as a CSS color.",
6950
+ defaultLight: "rgba(248, 250, 252, 0.96)",
6951
+ defaultDark: "rgba(30, 41, 59, 0.88)",
6952
+ usedBy: ["DataTable header"]
6953
+ },
6954
+ {
6955
+ name: "--grey-strong",
6956
+ description: "Hover background for neutral rows as a CSS color.",
6957
+ defaultLight: "rgba(241, 245, 249, 0.98)",
6958
+ defaultDark: "rgba(51, 65, 85, 0.92)",
6959
+ usedBy: ["DataTable row hover"]
6960
+ },
6961
+ {
6962
+ name: "--text",
6963
+ description: "Generic text color alias as a CSS color.",
6964
+ defaultLight: "hsl(var(--tw-foreground))",
6965
+ defaultDark: "hsl(var(--tw-foreground))",
6966
+ usedBy: ["Pagination", "legacy utility surfaces"]
6967
+ },
6968
+ {
6969
+ name: "--muted",
6970
+ description: "Generic muted text color alias as a CSS color.",
6971
+ defaultLight: "hsl(var(--tw-muted-foreground))",
6972
+ defaultDark: "hsl(var(--tw-muted-foreground))",
6973
+ usedBy: ["Pagination", "DataTable sort icon", "helper text"]
6974
+ },
6975
+ {
6976
+ name: "--accent",
6977
+ description: "Generic accent color alias as a CSS color.",
6978
+ defaultLight: "hsl(var(--tw-accent))",
6979
+ defaultDark: "hsl(var(--tw-accent))",
6980
+ usedBy: ["DataTable checkbox accent", "focus accents"]
6981
+ },
6982
+ {
6983
+ name: "--primary-grad-from",
6984
+ description: "Gradient start color in HSL triplet format.",
6985
+ defaultLight: "199 89% 48%",
6986
+ defaultDark: "198.6 88.7% 48.4%",
6987
+ usedBy: ["Button variant create"]
6988
+ },
6989
+ {
6990
+ name: "--primary-grad-to",
6991
+ description: "Gradient end color in HSL triplet format.",
6992
+ defaultLight: "221.2 83.2% 53.3%",
6993
+ defaultDark: "221.2 83.2% 53.3%",
6994
+ usedBy: ["Button variant create"]
6995
+ }
6996
+ ],
6997
+ exampleCss: `:root {
6998
+ --tw-primary: 12 88% 56%;
6999
+ --tw-accent: 24 95% 52%;
7000
+ --primary-grad-from: 24 95% 52%;
7001
+ --primary-grad-to: 12 88% 56%;
7002
+ --surface: rgba(255, 248, 240, 0.92);
7003
+ }
7004
+
7005
+ .dark {
7006
+ --tw-primary: 18 100% 62%;
7007
+ --tw-accent: 35 100% 58%;
7008
+ --surface: rgba(24, 24, 27, 0.82);
7009
+ }`
7010
+ };
7011
+ var uiProjectAiRules = [
7012
+ "Use @lucasvu/scope-ui as the default UI library.",
7013
+ "Import @lucasvu/scope-ui/styles.css once at the app entry.",
7014
+ "Import the project override theme file after the package stylesheet.",
7015
+ "Read uiAiManifest to choose the correct component by intent before coding.",
7016
+ "Read uiThemeContract before changing colors, shadows, or theme behavior.",
7017
+ "Prefer root exports and avoid MainFe unless the task explicitly targets a legacy screen."
7018
+ ];
7019
+
6538
7020
  exports.Alert = Alert;
6539
7021
  exports.ArgonSidebar = ArgonSidebar;
6540
7022
  exports.AsyncCombobox = AsyncCombobox;
@@ -6549,7 +7031,9 @@ exports.CardFooter = CardFooter;
6549
7031
  exports.CardHeader = CardHeader;
6550
7032
  exports.CardTitle = CardTitle;
6551
7033
  exports.Combobox = Combobox;
7034
+ exports.Control = FormControl;
6552
7035
  exports.DataTable = DataTable;
7036
+ exports.Description = FormDescription;
6553
7037
  exports.Field = FormField;
6554
7038
  exports.Form = Form;
6555
7039
  exports.FormControl = FormControl;
@@ -6559,9 +7043,12 @@ exports.FormItem = FormItem;
6559
7043
  exports.FormLabel = FormLabel;
6560
7044
  exports.FormMessage = FormMessage;
6561
7045
  exports.Input = Input;
7046
+ exports.Item = FormItem;
7047
+ exports.Label = FormLabel;
6562
7048
  exports.LineClampTooltip = LineClampTooltip;
6563
7049
  exports.Loading = Loading;
6564
7050
  exports.MainFe = main_fe_exports;
7051
+ exports.Message = FormMessage;
6565
7052
  exports.MultiSelect = MultiSelect;
6566
7053
  exports.NumericInput = NumericInput;
6567
7054
  exports.OverflowTooltip = OverflowTooltip;
@@ -6579,9 +7066,13 @@ exports.TableCell = TableCell;
6579
7066
  exports.TableHeader = TableHeader;
6580
7067
  exports.TableRow = TableRow;
6581
7068
  exports.Tabs = Tabs;
7069
+ exports.Textarea = Textarea;
6582
7070
  exports.Tooltip = Tooltip;
6583
7071
  exports.TruncatedText = TruncatedText;
6584
7072
  exports.cn = cn;
6585
7073
  exports.defaultPermissionChecker = defaultPermissionChecker;
6586
7074
  exports.filterSidebarItems = filterSidebarItems;
6587
7075
  exports.hasActiveDescendant = hasActiveDescendant;
7076
+ exports.uiAiManifest = uiAiManifest;
7077
+ exports.uiProjectAiRules = uiProjectAiRules;
7078
+ exports.uiThemeContract = uiThemeContract;