margo-ui 3.0.1 → 4.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "margo-ui",
3
- "version": "3.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "React UI kit built on Tailwind CSS v4 design tokens, themeable through plain CSS custom properties.",
5
5
  "keywords": [
6
6
  "react",
@@ -1 +1 @@
1
- export const blockquoteBaseClassName = "border-l-2 border-primary-darken py-0.5 pl-4";
1
+ export const blockquoteBaseClassName = "border-l-margo border-primary-darken py-0.5 pl-4";
@@ -1,4 +1,4 @@
1
- export const buttonBaseClassName = `group/button flex h-8 w-fit shrink-0 items-center px-2 rounded-lg border-2 text-on-main
1
+ export const buttonBaseClassName = `group/button flex h-8 w-fit shrink-0 items-center px-2 rounded-margo-1 border-margo text-on-main
2
2
  hover:border-on-main hover:text-on-main focus-visible:border-primary
3
3
  focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-on-main
4
4
  select-none origin-center transition-transform duration-[160ms] ease-out active:scale-[0.95] bg-main`;
@@ -1,4 +1,4 @@
1
- export const cardBaseClassName = "rounded-lg border-2 border-border bg-main p-5 text-on-main shadow-card";
1
+ export const cardBaseClassName = "rounded-margo-1 border-margo border-border bg-main p-5 text-on-main shadow-card";
2
2
 
3
3
  export const cardFocusClassName = `focus:border-primary focus-visible:outline focus-visible:outline-offset-1
4
4
  focus-visible:outline-on-main`;
@@ -1,5 +1,5 @@
1
- export const checkboxBaseClassName = `margo-checkbox size-5 flex-none cursor-pointer rounded-md border-2 border-border
1
+ export const checkboxBaseClassName = `margo-checkbox size-5 flex-none cursor-pointer rounded-margo-3/4 border-margo border-border
2
2
  bg-main p-1 text-on-main enabled:hover:border-on-main focus-visible:border-primary focus-visible:outline
3
3
  focus-visible:outline-offset-1 focus-visible:outline-on-main checked:border-primary indeterminate:border-primary
4
- select-none origin-center transition-transform duration-[120ms] ease-out active:scale-[0.95] disabled:cursor-auto
4
+ select-none origin-center transition-transform duration-[120ms] ease-out active:scale-[0.92] disabled:cursor-auto
5
5
  disabled:opacity-40`;
@@ -1,5 +1,5 @@
1
1
  export const chipBaseClassName = `bg-on-main/8 margo-text-box-trim flex items-center justify-center px-3 py-0.5
2
- whitespace-nowrap lowercase flex-none leading-none rounded-md text-mc shadow-chip
2
+ whitespace-nowrap lowercase flex-none leading-none rounded-margo-3/4 text-mc shadow-chip
3
3
  focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-on-main`;
4
4
 
5
5
  export const chipActiveClassName = "bg-on-main text-main";
@@ -1,3 +1,3 @@
1
1
  export const codeBaseClassName = "font-mono text-xs text-medium";
2
2
 
3
- export const codeFilledClassName = "rounded-sm bg-neutral/60 px-1 py-0.5 text-on-main/90";
3
+ export const codeFilledClassName = "rounded-margo-1/2 bg-neutral/60 px-1 py-0.5 text-on-main/90";
@@ -1,6 +1,6 @@
1
1
  export const dialogBaseClassName = `flex m-4 max-h-[calc(100%-2rem)] w-[calc(100%-2rem)] flex-col overflow-hidden
2
- rounded-lg border-2 border-border bg-main text-on-main shadow-sm`;
2
+ rounded-margo-1 border-margo border-border bg-main text-on-main shadow-sm`;
3
3
 
4
4
  export const dialogBodyClassName = "min-h-0 flex-1 overflow-y-auto px-5 py-4 text-sm";
5
5
 
6
- export const dialogFooterClassName = "flex items-center justify-end gap-2 border-t-2 border-border px-5 py-4";
6
+ export const dialogFooterClassName = "flex items-center justify-end gap-2 border-t-margo border-border px-5 py-4";
@@ -1,13 +1,15 @@
1
- export const inputBaseClassName = `group/input flex w-full cursor-text items-center gap-1 rounded-lg border-2 px-3 py-2 text-on-main
2
- text-sm select-none min-h-[2.5rem] bg-low
1
+ export const inputBaseClassName = `group/input flex h-10 w-full cursor-text items-center rounded-margo-1 border-margo text-on-main
2
+ text-sm select-none bg-low
3
3
  border-transparent text-medium hover:border-on-main hover:text-on-main hover:shadow-item
4
4
  focus-within:border-primary focus-within:text-on-main
5
5
  has-[input:disabled]:pointer-events-none has-[input:disabled]:cursor-auto has-[input:disabled]:opacity-40`;
6
6
 
7
7
  export const inputActiveClassName = "border-primary";
8
8
 
9
- export const inputIconClassName = `ml-auto flex size-4 flex-none shrink-0 items-center justify-center first:ml-0
9
+ export const inputIconClassName = `ml-auto flex h-full w-8 flex-none shrink-0 items-center justify-center pr-3 pl-1
10
+ first:ml-0 first:pr-1 first:pl-3
10
11
  [[data-margo-input-slot]+&]:ml-0`;
11
12
 
12
- export const inputTextClassName = `min-w-0 flex-1 truncate border-none bg-transparent text-left text-on-main outline-none
13
- placeholder:text-medium disabled:cursor-auto`;
13
+ export const inputTextClassName = `h-full min-w-0 flex-1 truncate border-none bg-transparent px-3 text-left text-on-main
14
+ outline-none placeholder:text-medium disabled:cursor-auto
15
+ [[data-margo-input-slot]+&]:pl-0 [&:has(+[data-margo-input-slot])]:pr-0`;
@@ -1,4 +1,4 @@
1
- export const itemBaseClassName = `group/item flex w-full cursor-pointer items-center gap-1 rounded-lg border-2 px-3 py-2 text-on-main
1
+ export const itemBaseClassName = `group/item flex w-full cursor-pointer items-center gap-1 rounded-margo-1 border-margo px-3 py-2 text-on-main
2
2
  text-sm focus-visible:border-primary focus-visible:outline select-none
3
3
  focus-visible:outline-offset-1 min-h-[2.5rem] hover:border-on-main focus-visible:outline-on-main
4
4
  origin-center bg-low transition-transform duration-[160ms] ease-out active:scale-[0.98]`;
@@ -3,7 +3,7 @@ import type { PopoverAlign, PopoverPosition } from "./type.js";
3
3
  export const popoverAnchorClassName = "relative inline-block size-fit";
4
4
 
5
5
  export const popoverBaseClassName = `margo-popover absolute z-20 m-0 flex w-max max-w-[calc(100vw-2rem)] flex-col
6
- overflow-clip rounded-lg border-2 border-border bg-main text-on-main shadow-card outline-none`;
6
+ overflow-clip rounded-margo-1 border-margo border-border bg-main text-on-main shadow-card outline-none`;
7
7
 
8
8
  export const popoverBodyClassName = `flex min-h-0 max-h-56 flex-col gap-1
9
9
  overflow-y-auto overscroll-contain w-64 p-2 text-sm`;
@@ -1,15 +1,15 @@
1
- export const selectBaseClassName = `group/select relative flex min-h-[2.5rem] w-full items-center gap-1 rounded-lg
2
- border-2 border-transparent bg-low text-sm text-medium select-none
1
+ export const selectBaseClassName = `group/select relative flex h-10 w-full items-center rounded-margo-1
2
+ border-margo border-transparent bg-low text-sm text-medium select-none
3
3
  hover:border-on-main hover:text-on-main hover:shadow-item
4
4
  focus-within:border-primary focus-within:text-on-main
5
5
  has-[select:disabled]:pointer-events-none has-[select:disabled]:opacity-40`;
6
6
 
7
7
  export const selectActiveClassName = "border-primary";
8
8
 
9
- export const selectControlClassName = `min-w-0 flex-1 cursor-pointer appearance-none truncate rounded-lg
10
- bg-transparent px-3 py-2 text-left text-on-main outline-none disabled:cursor-auto
9
+ export const selectControlClassName = `h-full min-w-0 flex-1 cursor-pointer appearance-none truncate rounded-margo-1
10
+ bg-transparent pl-3 text-left text-on-main outline-none disabled:cursor-auto
11
11
  has-[option[value='']:checked]:text-medium
12
12
  [&>option]:bg-main [&>option]:text-on-main
13
13
  [&>option:checked]:bg-primary-darken [&>option:checked]:text-on-main`;
14
14
 
15
- export const selectIconClassName = "pointer-events-none mr-3 flex size-4 flex-none items-center justify-center";
15
+ export const selectIconClassName = `pointer-events-none flex h-full w-8 flex-none items-center justify-center pr-3 pl-1`;
@@ -3,12 +3,12 @@ import type { SheetSide } from "./type.js";
3
3
  export const sheetBaseClassName = "margo-sheet flex flex-col overflow-hidden border-border bg-main text-on-main";
4
4
 
5
5
  export const sheetSideClassName: Record<SheetSide, string> = {
6
- start: "h-full w-[85%] max-w-[26rem] justify-self-start self-stretch border-r-2",
7
- end: "h-full w-[85%] max-w-[26rem] justify-self-end self-stretch border-l-2",
8
- top: "h-auto max-h-[40%] w-full self-start justify-self-stretch border-b-2",
9
- bottom: "h-auto max-h-[40%] w-full self-end justify-self-stretch border-t-2",
6
+ start: "h-full w-[85%] max-w-[26rem] justify-self-start self-stretch border-r-margo",
7
+ end: "h-full w-[85%] max-w-[26rem] justify-self-end self-stretch border-l-margo",
8
+ top: "h-auto max-h-[40%] w-full self-start justify-self-stretch border-b-margo",
9
+ bottom: "h-auto max-h-[40%] w-full self-end justify-self-stretch border-t-margo",
10
10
  };
11
11
 
12
12
  export const sheetBodyClassName = "min-h-0 flex-1 overflow-y-auto px-5 py-4 text-sm";
13
13
 
14
- export const sheetFooterClassName = "flex items-center justify-end gap-2 border-t-2 border-border px-5 py-4";
14
+ export const sheetFooterClassName = "flex items-center justify-end gap-2 border-t-margo border-border px-5 py-4";
@@ -1,12 +1,12 @@
1
- export const tableWrapperClassName = "w-full overflow-x-auto overscroll-x-none rounded-lg border-2 border-border";
1
+ export const tableWrapperClassName = "w-full overflow-x-auto overscroll-x-none rounded-margo-1 border-margo border-border";
2
2
 
3
3
  export const tableBaseClassName = "w-full border-collapse text-xs text-on-main";
4
4
 
5
- export const tableHeadClassName = "border-b-2 border-border bg-low text-left";
5
+ export const tableHeadClassName = "border-b-margo border-border bg-low text-left";
6
6
 
7
7
  export const tableBodyClassName = "align-top";
8
8
 
9
- export const tableRowClassName = "border-b-2 border-border last:border-b-0";
9
+ export const tableRowClassName = "border-b-margo border-border last:border-b-0";
10
10
 
11
11
  export const tableHeadCellClassName = "px-3 py-2 font-medium whitespace-nowrap";
12
12
 
@@ -1,4 +1,4 @@
1
- export const toggleBaseClassName = `margo-toggle h-5 w-9 flex-none cursor-pointer rounded-full border-2 border-border
1
+ export const toggleBaseClassName = `margo-toggle h-5 w-9 flex-none cursor-pointer rounded-full border-margo border-border
2
2
  bg-main p-0.5 text-on-main enabled:hover:border-on-main focus-visible:border-primary focus-visible:outline
3
3
  focus-visible:outline-offset-1 focus-visible:outline-on-main checked:border-primary select-none origin-center
4
- transition-transform duration-[160ms] ease-out active:scale-[0.98] disabled:cursor-auto disabled:opacity-40`;
4
+ transition-transform duration-[160ms] ease-out active:scale-[0.92] disabled:cursor-auto disabled:opacity-40`;
@@ -2,7 +2,6 @@
2
2
  appearance: none;
3
3
  }
4
4
 
5
- /* the thumb travels the track's width minus its height: borders and padding cancel out on both axes */
6
5
  .margo-toggle::before {
7
6
  content: "";
8
7
  display: block;
@@ -2,7 +2,7 @@ import type { TooltipPosition } from "./type.js";
2
2
 
3
3
  export const tooltipAnchorClassName = "group relative inline-block size-fit";
4
4
 
5
- export const tooltipBubbleClassName = `pointer-events-none absolute z-10 rounded-sm bg-on-main px-2 py-0.5 text-xs text-main lowercase
5
+ export const tooltipBubbleClassName = `pointer-events-none absolute z-10 rounded-margo-1/2 bg-on-main px-2 py-0.5 text-xs text-main lowercase
6
6
  whitespace-nowrap opacity-0`;
7
7
 
8
8
  export const tooltipTransitionClassName = "transition-opacity duration-[250ms] ease-in-out";
package/src/css/theme.css CHANGED
@@ -39,8 +39,13 @@
39
39
  --z-index-layer: var(--margo-layer-z-index);
40
40
  --z-index-max: var(--margo-max-z-index);
41
41
 
42
+ /* Radii */
43
+ --radius-margo-1: var(--margo-radius);
44
+ --radius-margo-3\/4: calc(var(--margo-radius) * 3 / 4);
45
+ --radius-margo-1\/2: calc(var(--margo-radius) / 2);
46
+
42
47
  /* Border widths */
43
- --border-width-2: var(--margo-border-width-2);
48
+ --border-width-margo: var(--margo-border);
44
49
 
45
50
  /* Font weights */
46
51
  --font-weight-thin: var(--margo-font-weight-thin);
@@ -29,7 +29,9 @@
29
29
  --margo-font-weight-extrabold: 800;
30
30
  --margo-font-weight-black: 900;
31
31
 
32
- --margo-border-width-2: 1.5px;
32
+ --margo-radius: 0.5rem;
33
+
34
+ --margo-border: 1.5px;
33
35
 
34
36
  --margo-layer-duration: 750ms;
35
37
  --margo-layer-easing: cubic-bezier(0.32, 0.72, 0, 1);
@@ -19,9 +19,9 @@
19
19
  }
20
20
 
21
21
  .margo-border-glow--ring::before {
22
- inset: calc(-1 * var(--border-width-2));
22
+ inset: calc(-1 * var(--margo-border));
23
23
  border-radius: inherit;
24
- padding: var(--border-width-2);
24
+ padding: var(--margo-border);
25
25
  mask:
26
26
  linear-gradient(#000 0 0) content-box,
27
27
  linear-gradient(#000 0 0);
@@ -30,21 +30,21 @@
30
30
  }
31
31
 
32
32
  .margo-border-glow--edge-top::before {
33
- inset: calc(-1 * var(--border-width-2)) 0 auto 0;
34
- height: var(--border-width-2);
33
+ inset: calc(-1 * var(--margo-border)) 0 auto 0;
34
+ height: var(--margo-border);
35
35
  }
36
36
 
37
37
  .margo-border-glow--edge-bottom::before {
38
- inset: auto 0 calc(-1 * var(--border-width-2)) 0;
39
- height: var(--border-width-2);
38
+ inset: auto 0 calc(-1 * var(--margo-border)) 0;
39
+ height: var(--margo-border);
40
40
  }
41
41
 
42
42
  .margo-border-glow--edge-left::before {
43
- inset: 0 auto 0 calc(-1 * var(--border-width-2));
44
- width: var(--border-width-2);
43
+ inset: 0 auto 0 calc(-1 * var(--margo-border));
44
+ width: var(--margo-border);
45
45
  }
46
46
 
47
47
  .margo-border-glow--edge-right::before {
48
- inset: 0 calc(-1 * var(--border-width-2)) 0 auto;
49
- width: var(--border-width-2);
48
+ inset: 0 calc(-1 * var(--margo-border)) 0 auto;
49
+ width: var(--margo-border);
50
50
  }
@@ -7,6 +7,25 @@ const isNumber = (value: string) => /^\d+$/.test(value);
7
7
 
8
8
  const isColumnLine = (value: string) => value === "full" || value === "content" || isNumber(value);
9
9
 
10
+ const isMargoStep = (value: string) => /^margo-\d+(\/\d+)?$/.test(value);
11
+
12
+ const BORDER_SIDES = ["", "x", "y", "s", "e", "t", "r", "b", "l"] as const;
13
+ const RADIUS_CORNERS = ["", "s", "e", "t", "r", "b", "l", "ss", "se", "ee", "es", "tl", "tr", "br", "bl"] as const;
14
+
15
+ const borderWidthGroups = Object.fromEntries(
16
+ BORDER_SIDES.map((side) => [
17
+ side ? `border-w-${side}` : "border-w",
18
+ [{ [side ? `border-${side}` : "border"]: ["margo"] }],
19
+ ]),
20
+ );
21
+
22
+ const radiusGroups = Object.fromEntries(
23
+ RADIUS_CORNERS.map((corner) => [
24
+ corner ? `rounded-${corner}` : "rounded",
25
+ [{ [corner ? `rounded-${corner}` : "rounded"]: [isMargoStep] }],
26
+ ]),
27
+ );
28
+
10
29
  type MargoClassGroupIds =
11
30
  | "margo-col"
12
31
  | "margo-col-start"
@@ -24,6 +43,8 @@ const twMerge = extendTailwindMerge<MargoClassGroupIds>({
24
43
  extend: {
25
44
  classGroups: {
26
45
  "font-size": ["text-mc"],
46
+ ...borderWidthGroups,
47
+ ...radiusGroups,
27
48
  "margo-col": [{ "margo-col": [isColumnLine] }],
28
49
  "margo-col-start": [{ "margo-col-start": [isColumnLine] }],
29
50
  "margo-col-end": [{ "margo-col-end": [isColumnLine] }],