@olundot/ui 0.24.0 → 0.25.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @olundot/ui
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a848a56: DataTable `isRowSelectable`가 `'hidden'`을 돌려주면 그 행의 선택 칸을 비웁니다.
8
+
9
+ - 폴더처럼 처음부터 고를 대상이 아닌 행에 씁니다. 체크박스 없이 같은 폭의 빈 칸을 둬 열이 어긋나지 않습니다. 1024px 미만 카드도 제목이 같은 자리에서 시작합니다.
10
+ - 선택 규칙은 `false`(막힌 행)와 같습니다. 전체 선택, 선택 개수, `onSelectionChange`에서 빠지고 `selectedIds`에 들어 있어도 선택으로 그리지 않습니다.
11
+ - 반환 타입만 `boolean | 'hidden'`으로 넓혔습니다. `boolean`을 돌려주는 코드는 그대로 동작합니다.
12
+
3
13
  ## 0.24.0
4
14
 
5
15
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -66,7 +66,7 @@ type GhostDefaultActionStyle = {
66
66
  declare const buttonCva: (props?: ({
67
67
  appearance?: "filled" | "outline" | "ghost" | "link" | null | undefined;
68
68
  tone?: "primary" | "neutral" | "danger" | null | undefined;
69
- size?: "xs" | "sm" | "md" | "lg" | "xl" | "default" | null | undefined;
69
+ size?: "default" | "md" | "xs" | "sm" | "lg" | "xl" | null | undefined;
70
70
  } & class_variance_authority_types.ClassProp) | undefined) => string;
71
71
  type ButtonVariantsOptions = Parameters<typeof buttonCva>[0];
72
72
  declare function buttonVariants(options?: ButtonVariantsOptions): string;
@@ -101,13 +101,13 @@ type CopyButtonProps = Omit<ButtonProps, 'appearance' | 'children' | 'loading' |
101
101
  declare const CopyButton: React.ForwardRefExoticComponent<CopyButtonProps & React.RefAttributes<HTMLButtonElement>>;
102
102
 
103
103
  declare const inputVariants: (props?: ({
104
- size?: "sm" | "md" | "lg" | null | undefined;
104
+ size?: "md" | "sm" | "lg" | null | undefined;
105
105
  fullWidth?: boolean | null | undefined;
106
106
  surface?: SurfaceLevel | null | undefined;
107
107
  } & class_variance_authority_types.ClassProp) | undefined) => string;
108
108
  declare const inputMessageVariants: (props?: ({
109
- state?: "error" | "success" | "default" | null | undefined;
110
- size?: "sm" | "md" | "lg" | null | undefined;
109
+ state?: "default" | "error" | "success" | null | undefined;
110
+ size?: "md" | "sm" | "lg" | null | undefined;
111
111
  } & class_variance_authority_types.ClassProp) | undefined) => string;
112
112
  type InputState = NonNullable<VariantProps<typeof inputMessageVariants>["state"]>;
113
113
  /** Canonical size type (0.2.0+). Use `size` prop with these values. */
@@ -155,11 +155,11 @@ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "
155
155
  declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
156
156
 
157
157
  declare const fileUploadZoneVariants: (props?: ({
158
- size?: "compact" | "default" | null | undefined;
158
+ size?: "default" | "compact" | null | undefined;
159
159
  surface?: SurfaceLevel | null | undefined;
160
160
  } & class_variance_authority_types.ClassProp) | undefined) => string;
161
161
  declare const fileUploadIconVariants: (props?: ({
162
- size?: "compact" | "default" | null | undefined;
162
+ size?: "default" | "compact" | null | undefined;
163
163
  } & class_variance_authority_types.ClassProp) | undefined) => string;
164
164
  interface FileUploadZoneProps extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "onChange">, VariantProps<typeof fileUploadZoneVariants> {
165
165
  accept?: string;
@@ -203,12 +203,12 @@ interface InlineAlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'childre
203
203
  declare const InlineAlert: React.ForwardRefExoticComponent<InlineAlertProps & React.RefAttributes<HTMLDivElement>>;
204
204
 
205
205
  declare const textareaVariants: (props?: ({
206
- size?: "sm" | "md" | "lg" | null | undefined;
206
+ size?: "md" | "sm" | "lg" | null | undefined;
207
207
  fullWidth?: boolean | null | undefined;
208
208
  surface?: SurfaceLevel | null | undefined;
209
209
  } & class_variance_authority_types.ClassProp) | undefined) => string;
210
210
  declare const textareaMessageVariants: (props?: ({
211
- state?: "error" | "success" | "default" | null | undefined;
211
+ state?: "default" | "error" | "success" | null | undefined;
212
212
  } & class_variance_authority_types.ClassProp) | undefined) => string;
213
213
  type TextareaState = NonNullable<VariantProps<typeof textareaMessageVariants>["state"]>;
214
214
  /** Canonical size type (0.2.0+). Use `size` prop with these values. */
@@ -257,14 +257,14 @@ interface TextareaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaEl
257
257
  declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
258
258
 
259
259
  declare const selectVariants: (props?: ({
260
- size?: "sm" | "md" | "lg" | null | undefined;
260
+ size?: "md" | "sm" | "lg" | null | undefined;
261
261
  fullWidth?: boolean | null | undefined;
262
262
  appearance?: "inline" | "field" | null | undefined;
263
263
  surface?: SurfaceLevel | null | undefined;
264
264
  } & class_variance_authority_types.ClassProp) | undefined) => string;
265
265
  declare const selectMessageVariants: (props?: ({
266
- state?: "error" | "success" | "default" | null | undefined;
267
- size?: "sm" | "md" | "lg" | null | undefined;
266
+ state?: "default" | "error" | "success" | null | undefined;
267
+ size?: "md" | "sm" | "lg" | null | undefined;
268
268
  } & class_variance_authority_types.ClassProp) | undefined) => string;
269
269
  type SelectState = NonNullable<VariantProps<typeof selectMessageVariants>["state"]>;
270
270
  /** Canonical size type (0.2.0+). Use `size` prop with these values. */
@@ -1207,9 +1207,11 @@ interface DataTableBaseProps<T> extends Omit<React.HTMLAttributes<HTMLDivElement
1207
1207
  /**
1208
1208
  * With `selectable`, `false` blocks a row's selection: its checkbox is disabled, it is never
1209
1209
  * drawn selected or passed to `onSelectionChange`, and select-all counts only the other rows.
1210
+ * `'hidden'` blocks it the same way and draws no checkbox, for a row that is never selected (a
1211
+ * folder among items); its slot stays empty at the checkbox width, so the columns line up.
1210
1212
  * Navigating, expanding and the row menu still work.
1211
1213
  */
1212
- isRowSelectable?: (row: T) => boolean;
1214
+ isRowSelectable?: (row: T) => boolean | 'hidden';
1213
1215
  selectedIds?: Set<string>;
1214
1216
  onSelectionChange?: (ids: Set<string>) => void;
1215
1217
  /** Unit in the screen-reader selection message — `12명 선택됨`. Defaults to `개`. */
@@ -1789,7 +1791,7 @@ interface StatusDotProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'ch
1789
1791
  declare const StatusDot: React.ForwardRefExoticComponent<StatusDotProps & React.RefAttributes<HTMLSpanElement>>;
1790
1792
 
1791
1793
  declare const notificationBadgeVariants: (props?: ({
1792
- size?: "sm" | "md" | null | undefined;
1794
+ size?: "md" | "sm" | null | undefined;
1793
1795
  placement?: "none" | "inline" | "corner" | null | undefined;
1794
1796
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1795
1797
  type NotificationBadgeSize = NonNullable<VariantProps<typeof notificationBadgeVariants>['size']>;
@@ -1802,13 +1804,13 @@ declare const NotificationBadge: React.ForwardRefExoticComponent<NotificationBad
1802
1804
 
1803
1805
  declare const chipVariants: (props?: ({
1804
1806
  variant?: "filter" | "choice" | "removable" | "status-filter" | null | undefined;
1805
- tone?: "muted" | "accent" | "warning" | "success" | "neutral" | "danger" | null | undefined;
1806
- size?: "sm" | "md" | "lg" | null | undefined;
1807
+ tone?: "accent" | "neutral" | "danger" | "success" | "warning" | "muted" | null | undefined;
1808
+ size?: "md" | "sm" | "lg" | null | undefined;
1807
1809
  pressed?: boolean | null | undefined;
1808
1810
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1809
1811
  declare const chipCountVariants: (props?: ({
1810
- tone?: "muted" | "accent" | "warning" | "success" | "neutral" | "danger" | null | undefined;
1811
- size?: "sm" | "md" | "lg" | null | undefined;
1812
+ tone?: "accent" | "neutral" | "danger" | "success" | "warning" | "muted" | null | undefined;
1813
+ size?: "md" | "sm" | "lg" | null | undefined;
1812
1814
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1813
1815
  type ChipVariant = NonNullable<VariantProps<typeof chipVariants>["variant"]>;
1814
1816
  type ChipTone = NonNullable<VariantProps<typeof chipVariants>["tone"]>;
@@ -1822,7 +1824,7 @@ interface ChipProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>,
1822
1824
  declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLButtonElement>>;
1823
1825
 
1824
1826
  declare const emptyStateBaseVariants: (props?: ({
1825
- size?: "sm" | "md" | "lg" | null | undefined;
1827
+ size?: "md" | "sm" | "lg" | null | undefined;
1826
1828
  bordered?: boolean | null | undefined;
1827
1829
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1828
1830
  type EmptyStateTone = "neutral" | "muted" | "raised";
@@ -1834,7 +1836,7 @@ interface EmptyStateVariantOptions extends VariantProps<typeof emptyStateBaseVar
1834
1836
  }
1835
1837
  declare function emptyStateVariants({ size, tone, surface, bordered, className, }?: EmptyStateVariantOptions): string;
1836
1838
  declare const emptyStateIconVariants: (props?: ({
1837
- size?: "sm" | "md" | "lg" | null | undefined;
1839
+ size?: "md" | "sm" | "lg" | null | undefined;
1838
1840
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1839
1841
  type EmptyStateSize = NonNullable<VariantProps<typeof emptyStateBaseVariants>["size"]>;
1840
1842
  interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof emptyStateBaseVariants> {
@@ -1860,7 +1862,7 @@ interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "ti
1860
1862
  declare const EmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
1861
1863
 
1862
1864
  declare const errorStateVariants: (props?: ({
1863
- size?: "sm" | "md" | "lg" | null | undefined;
1865
+ size?: "md" | "sm" | "lg" | null | undefined;
1864
1866
  surface?: SurfaceLevel | null | undefined;
1865
1867
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1866
1868
  interface ErrorStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof errorStateVariants> {
@@ -1880,7 +1882,7 @@ declare const skeletonVariants: (props?: ({
1880
1882
  shape?: "text" | "block" | "circle" | null | undefined;
1881
1883
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1882
1884
  declare const spinnerVariants: (props?: ({
1883
- size?: "sm" | "md" | "lg" | 16 | 24 | 32 | null | undefined;
1885
+ size?: "md" | "sm" | "lg" | 16 | 24 | 32 | null | undefined;
1884
1886
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1885
1887
  interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof skeletonVariants> {
1886
1888
  }
@@ -1913,7 +1915,7 @@ interface SpinnerProps extends React.HTMLAttributes<HTMLSpanElement> {
1913
1915
  declare const Spinner: React.ForwardRefExoticComponent<SpinnerProps & React.RefAttributes<HTMLSpanElement>>;
1914
1916
 
1915
1917
  declare const iconButtonCva: (props?: ({
1916
- size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
1918
+ size?: "md" | "xs" | "sm" | "lg" | "xl" | null | undefined;
1917
1919
  pressed?: boolean | null | undefined;
1918
1920
  appearance?: "filled" | "outline" | "ghost" | null | undefined;
1919
1921
  tone?: "primary" | "neutral" | "danger" | null | undefined;
@@ -1922,7 +1924,7 @@ type IconButtonSize = NonNullable<VariantProps<typeof iconButtonCva>["size"]>;
1922
1924
  type IconButtonVariantsOptions = NonNullable<Parameters<typeof iconButtonCva>[0]>;
1923
1925
  declare function iconButtonVariants(options?: IconButtonVariantsOptions): string;
1924
1926
  declare const iconButtonBadgeVariants: (props?: ({
1925
- tone?: "error" | "info" | "success" | null | undefined;
1927
+ tone?: "error" | "success" | "info" | null | undefined;
1926
1928
  } & class_variance_authority_types.ClassProp) | undefined) => string;
1927
1929
  type IconButtonBadgeTone = NonNullable<VariantProps<typeof iconButtonBadgeVariants>["tone"]>;
1928
1930
  type IconButtonIcon = React.ComponentType<React.SVGProps<SVGSVGElement> & {
@@ -2185,7 +2187,7 @@ interface ActionFooterProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
2185
2187
  declare const ActionFooter: React.ForwardRefExoticComponent<ActionFooterProps & React.RefAttributes<HTMLDivElement>>;
2186
2188
 
2187
2189
  declare const toastVariants: (props?: ({
2188
- variant?: "error" | "warning" | "info" | "success" | "default" | null | undefined;
2190
+ variant?: "default" | "error" | "success" | "info" | "warning" | null | undefined;
2189
2191
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2190
2192
  declare const toastViewportVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
2191
2193
  type ToastVariant = NonNullable<VariantProps<typeof toastVariants>['variant']>;
@@ -2239,19 +2241,19 @@ interface ToastProviderProps extends React.HTMLAttributes<HTMLDivElement> {
2239
2241
  declare function ToastProvider({ children, maxToasts, className, ...props }: ToastProviderProps): react_jsx_runtime.JSX.Element;
2240
2242
 
2241
2243
  declare const otpFieldVariants: (props?: ({
2242
- size?: "compact" | "default" | null | undefined;
2244
+ size?: "default" | "compact" | null | undefined;
2243
2245
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2244
2246
  declare const otpFieldGroupVariants: (props?: ({
2245
- size?: "compact" | "default" | null | undefined;
2247
+ size?: "default" | "compact" | null | undefined;
2246
2248
  fluid?: boolean | null | undefined;
2247
2249
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2248
2250
  declare const otpCellVariants: (props?: ({
2249
- size?: "compact" | "default" | null | undefined;
2251
+ size?: "default" | "compact" | null | undefined;
2250
2252
  fluid?: boolean | null | undefined;
2251
2253
  surface?: SurfaceLevel | null | undefined;
2252
2254
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2253
2255
  declare const otpFieldMessageVariants: (props?: ({
2254
- state?: "error" | "default" | null | undefined;
2256
+ state?: "default" | "error" | null | undefined;
2255
2257
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2256
2258
  type OTPFieldSize = NonNullable<VariantProps<typeof otpCellVariants>["size"]>;
2257
2259
  interface OTPFieldProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, "onChange" | "children" | "defaultValue" | "value">, VariantProps<typeof otpFieldVariants> {
@@ -2278,10 +2280,10 @@ interface OTPFieldProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetEl
2278
2280
  declare const OTPField: React.ForwardRefExoticComponent<OTPFieldProps & React.RefAttributes<HTMLFieldSetElement>>;
2279
2281
 
2280
2282
  declare const searchFieldVariants: (props?: ({
2281
- size?: "sm" | "md" | "lg" | null | undefined;
2283
+ size?: "md" | "sm" | "lg" | null | undefined;
2282
2284
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2283
2285
  declare const searchFieldInputVariants: (props?: ({
2284
- size?: "sm" | "md" | "lg" | null | undefined;
2286
+ size?: "md" | "sm" | "lg" | null | undefined;
2285
2287
  hasClear?: boolean | null | undefined;
2286
2288
  surface?: SurfaceLevel | null | undefined;
2287
2289
  } & class_variance_authority_types.ClassProp) | undefined) => string;
@@ -2305,7 +2307,7 @@ declare const checkboxVariants: (props?: ({
2305
2307
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2306
2308
  declare const checkboxRootVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
2307
2309
  declare const checkboxBoxVariants: (props?: ({
2308
- size?: "sm" | "md" | null | undefined;
2310
+ size?: "md" | "sm" | null | undefined;
2309
2311
  } & class_variance_authority_types.ClassProp) | undefined) => string;
2310
2312
  declare const checkboxGroupItemVariants: (props?: ({
2311
2313
  appearance?: "card" | "plain" | null | undefined;
package/dist/index.js CHANGED
@@ -8653,8 +8653,19 @@ function RowCheckbox({
8653
8653
  columns,
8654
8654
  selected,
8655
8655
  selectionBlocked,
8656
+ selectionHidden,
8656
8657
  onToggle
8657
8658
  }) {
8659
+ if (selectionHidden) {
8660
+ return /* @__PURE__ */ jsx39(
8661
+ "span",
8662
+ {
8663
+ "aria-hidden": "true",
8664
+ "data-slot": "data-table-row-checkbox-placeholder",
8665
+ className: "block h-[calc(var(--space-4)+var(--space-1))] w-[calc(var(--space-4)+var(--space-1)+var(--space-3))] shrink-0"
8666
+ }
8667
+ );
8668
+ }
8658
8669
  return /* @__PURE__ */ jsx39(
8659
8670
  Checkbox,
8660
8671
  {
@@ -8765,6 +8776,7 @@ function DataTableRowView({
8765
8776
  selectable,
8766
8777
  selected,
8767
8778
  selectionBlocked,
8779
+ selectionHidden,
8768
8780
  visuallySelected,
8769
8781
  href,
8770
8782
  activatable,
@@ -8801,7 +8813,7 @@ function DataTableRowView({
8801
8813
  } : handlers.onClick,
8802
8814
  onKeyDown: handlers.onKeyDown,
8803
8815
  children: [
8804
- selectable ? /* @__PURE__ */ jsx39("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, onToggle }) }) : null,
8816
+ selectable ? /* @__PURE__ */ jsx39("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, selectionHidden, onToggle }) }) : null,
8805
8817
  columns.map((column, columnIndex) => {
8806
8818
  const align = column.align ?? "left";
8807
8819
  const content = getRenderedCell(row, column);
@@ -8875,6 +8887,7 @@ function DataTableMobileCardView({
8875
8887
  selectable,
8876
8888
  selected,
8877
8889
  selectionBlocked,
8890
+ selectionHidden,
8878
8891
  visuallySelected,
8879
8892
  href,
8880
8893
  activatable,
@@ -8901,7 +8914,7 @@ function DataTableMobileCardView({
8901
8914
  const navigable = linked || activatable;
8902
8915
  const opened = useOpenedOnce(expand?.expanded ?? false);
8903
8916
  const leading = selectable || content.leading != null ? /* @__PURE__ */ jsxs35("span", { className: "flex items-center gap-[var(--space-2)]", children: [
8904
- selectable ? /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, onToggle }) : null,
8917
+ selectable ? /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, selectionHidden, onToggle }) : null,
8905
8918
  content.leading
8906
8919
  ] }) : void 0;
8907
8920
  let title = content.title;
@@ -9381,9 +9394,19 @@ function DataTableInner({
9381
9394
  mobile: () => mobileListRef.current ?? mobileRef.current
9382
9395
  }
9383
9396
  });
9384
- const blockedIds = new Set(
9385
- selectable && isRowSelectable ? data.filter((row) => !isRowSelectable(row)).map((row) => getRowId(row, keyField)) : []
9386
- );
9397
+ const blockedIds = /* @__PURE__ */ new Set();
9398
+ const hiddenIds = /* @__PURE__ */ new Set();
9399
+ if (selectable && isRowSelectable) {
9400
+ data.forEach((row) => {
9401
+ const verdict = isRowSelectable(row);
9402
+ if (verdict === "hidden") {
9403
+ hiddenIds.add(getRowId(row, keyField));
9404
+ }
9405
+ if (!verdict || verdict === "hidden") {
9406
+ blockedIds.add(getRowId(row, keyField));
9407
+ }
9408
+ });
9409
+ }
9387
9410
  const selectableRowIds = rowIds.filter((id) => !blockedIds.has(id));
9388
9411
  const resolvedSelectedIds = selectedIds ?? /* @__PURE__ */ new Set();
9389
9412
  const selectedCount = selectableRowIds.filter((id) => resolvedSelectedIds.has(id)).length;
@@ -9506,6 +9529,7 @@ function DataTableInner({
9506
9529
  const getItemProps = (row, layout, index) => {
9507
9530
  const rowId = getRowId(row, keyField);
9508
9531
  const selectionBlocked = blockedIds.has(rowId);
9532
+ const selectionHidden = hiddenIds.has(rowId);
9509
9533
  const selected = !selectionBlocked && resolvedSelectedIds.has(rowId);
9510
9534
  const href = rowHref?.(row);
9511
9535
  const linked = Boolean(linkComponent && href);
@@ -9516,6 +9540,7 @@ function DataTableInner({
9516
9540
  selectable,
9517
9541
  selected,
9518
9542
  selectionBlocked,
9543
+ selectionHidden,
9519
9544
  visuallySelected: selected || rowId === activeRowId || rowId === contextMenu?.rowId,
9520
9545
  href,
9521
9546
  activatable: !linked && Boolean(href || onRowClick),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olundot/ui",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "OLUN. shared React UI components built on OLUN design tokens",
5
5
  "license": "MIT",
6
6
  "keywords": [