@joshwilkerson/flex-ui 1.0.0-alpha.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/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # flex-ui
2
+
3
+ CSS-first responsive flexbox layouts using data attributes. Works with plain HTML or as React components.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install flex-ui
9
+ ```
10
+
11
+ ## CSS-Only Usage
12
+
13
+ Include the CSS and use data attributes directly on your HTML:
14
+
15
+ ```html
16
+ <link rel="stylesheet" href="node_modules/flex-ui/dist/flex-ui.css" />
17
+
18
+ <div data-flex data-axis="horizontal" data-gap="2" data-align="center">
19
+ <div>Item 1</div>
20
+ <div>Item 2</div>
21
+ <div>Item 3</div>
22
+ </div>
23
+ ```
24
+
25
+ ### Flex Container
26
+
27
+ Add the `data-flex` attribute and configure with data attributes:
28
+
29
+ | Attribute | Values | Description |
30
+ |---|---|---|
31
+ | `data-axis` | `horizontal`, `vertical` | Flex direction |
32
+ | `data-gap` | `0`-`10`, `half`, `fourth` | Gap between items |
33
+ | `data-row-gap` | `0`-`10`, `half`, `fourth` | Row gap |
34
+ | `data-column-gap` | `0`-`10`, `half`, `fourth` | Column gap |
35
+ | `data-justify` | `start`, `end`, `center`, `between`, `around`, `evenly` | Main axis alignment |
36
+ | `data-align` | `start`, `end`, `center`, `stretch`, `baseline` | Cross axis alignment |
37
+ | `data-align-content` | `start`, `end`, `center`, `stretch`, `between`, `around`, `evenly` | Multi-line alignment |
38
+ | `data-wrap` | `nowrap`, `wrap`, `wrap-reverse` | Wrap behavior |
39
+ | `data-reverse` | (boolean) | Reverse direction |
40
+ | `data-inline` | (boolean) | Use `inline-flex` |
41
+
42
+ ### Flex Item
43
+
44
+ Add the `data-flex-item` attribute to children for additional control:
45
+
46
+ | Attribute | Values | Description |
47
+ |---|---|---|
48
+ | `data-grow` | `0`-`5` | Flex grow |
49
+ | `data-shrink` | `0`-`3` | Flex shrink |
50
+ | `data-basis` | `auto`, `0`, `full`, `1/2`, `1/3`, `2/3`, `1/4`, `3/4` | Flex basis |
51
+ | `data-align-self` | `auto`, `start`, `end`, `center`, `stretch`, `baseline` | Override container alignment |
52
+ | `data-order` | `1`-`12`, `first`, `last`, `none` | Visual order |
53
+
54
+ ### Responsive
55
+
56
+ Append a breakpoint suffix to any attribute for responsive behavior:
57
+
58
+ ```html
59
+ <!-- Vertical on mobile, horizontal from md up -->
60
+ <div data-flex data-axis="vertical" data-axis-md="horizontal" data-gap="1" data-gap-lg="3">
61
+ <div>Item 1</div>
62
+ <div>Item 2</div>
63
+ </div>
64
+ ```
65
+
66
+ Breakpoints: `xs` (480px), `sm` (600px), `md` (720px), `lg` (960px), `xl` (1200px)
67
+
68
+ ## React Components
69
+
70
+ Optional React wrapper that outputs the same data attributes:
71
+
72
+ ```tsx
73
+ import { Flex, FlexItem } from "flex-ui/react"
74
+ import "flex-ui" // include the CSS
75
+
76
+ <Flex axis="horizontal" gap={2} align="center">
77
+ <FlexItem grow={1}>Main</FlexItem>
78
+ <FlexItem basis="1/4">Sidebar</FlexItem>
79
+ </Flex>
80
+ ```
81
+
82
+ Props accept responsive objects:
83
+
84
+ ```tsx
85
+ <Flex
86
+ axis={{ base: "vertical", md: "horizontal" }}
87
+ gap={{ base: 1, lg: 3 }}
88
+ >
89
+ <FlexItem basis={{ base: "full", md: "1/2" }}>Half</FlexItem>
90
+ <FlexItem basis={{ base: "full", md: "1/2" }}>Half</FlexItem>
91
+ </Flex>
92
+ ```
93
+
94
+ ## Spacing Scale
95
+
96
+ The default spacing scale uses an 8px base unit:
97
+
98
+ | Key | Value |
99
+ |---|---|
100
+ | `0` | 0 |
101
+ | `fourth` | 2px |
102
+ | `half` | 4px |
103
+ | `1` | 8px |
104
+ | `2` | 16px |
105
+ | `3` | 24px |
106
+ | `4` | 32px |
107
+ | `5` | 40px |
108
+ | `6` | 48px |
109
+ | `7` | 56px |
110
+ | `8` | 64px |
111
+ | `9` | 72px |
112
+ | `10` | 80px |
113
+
114
+ Override spacing at runtime with CSS custom properties:
115
+
116
+ ```css
117
+ :root {
118
+ --flex-spacing-2: 1rem;
119
+ --flex-spacing-half: 0.125rem;
120
+ }
121
+ ```
122
+
123
+ ## Customization
124
+
125
+ Generate a custom CSS file with your own breakpoints and spacing:
126
+
127
+ ```bash
128
+ npx flex-ui
129
+ ```
130
+
131
+ The interactive CLI walks you through:
132
+
133
+ 1. Adjusting breakpoint values (xs, sm, md, lg, xl)
134
+ 2. Setting a base spacing unit (e.g., `4px`, `0.5rem`)
135
+ 3. Choosing an output path
136
+
137
+ The generated CSS replaces the default `flex-ui.css` with your custom values.
138
+
139
+ ## License
140
+
141
+ MIT
package/bin/flex-ui.ts ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env npx tsx
2
+ /**
3
+ * Flex UI CLI
4
+ *
5
+ * Usage:
6
+ * npx flex-ui Interactive customization + CSS generation
7
+ * npx flex-ui --help Show help
8
+ */
9
+
10
+ import "../scripts/cli.js"
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function c(t){return"unit"in t&&"scale"in t}function f(t){if(!c(t))return t;const{unit:i,scale:r}=t,n=i.match(/^([\d.]+)(.+)$/);if(!n)throw new Error(`Invalid spacing unit: ${i}. Expected format like "4px" or "0.25rem"`);const s=parseFloat(n[1]),l=n[2],e={};for(const o of r){const a=s*o;e[o]=a===0?"0":`${a}${l}`}return e}const u={unit:"8px",scale:[0,1,2,3,4,5,6,7,8,9,10]},p={fourth:"2px",half:"4px"},g={breakpoints:{xs:480,sm:600,md:720,lg:960,xl:1200},spacing:u,output:"./flex-ui.css"};exports.defaultConfig=g;exports.defaultSpacingConfig=u;exports.isSpacingWithUnit=c;exports.namedSpacing=p;exports.resolveSpacing=f;
@@ -0,0 +1,78 @@
1
+ export declare type DefaultBreakpoint = keyof typeof defaultConfig.breakpoints;
2
+
3
+ /**
4
+ * Default configuration values
5
+ */
6
+ export declare const defaultConfig: {
7
+ readonly breakpoints: {
8
+ readonly xs: 480;
9
+ readonly sm: 600;
10
+ readonly md: 720;
11
+ readonly lg: 960;
12
+ readonly xl: 1200;
13
+ };
14
+ readonly spacing: SpacingConfig;
15
+ readonly output: "./flex-ui.css";
16
+ };
17
+
18
+ export declare type DefaultSpacing = (typeof defaultSpacingConfig.scale)[number];
19
+
20
+ /**
21
+ * Default spacing using unit + scale format
22
+ */
23
+ export declare const defaultSpacingConfig: SpacingConfig;
24
+
25
+ export declare interface FlexConfig {
26
+ /**
27
+ * Custom breakpoints (min-width in pixels)
28
+ * @example { sm: 640, md: 768, lg: 1024, xl: 1280 }
29
+ */
30
+ breakpoints?: Record<string, number>;
31
+ /**
32
+ * Custom spacing - either explicit values or unit + multipliers
33
+ * @example { unit: '4px', scale: [0, 1, 2, 3, 4, 6, 8] }
34
+ * @example { 0: '0', 1: '0.25rem', 2: '0.5rem', 4: '1rem' }
35
+ */
36
+ spacing?: SpacingConfig | Record<string | number, string>;
37
+ /**
38
+ * Output file path for generated CSS (relative to cwd)
39
+ * @default "./flex-ui.css"
40
+ */
41
+ output?: string;
42
+ }
43
+
44
+ /**
45
+ * Check if spacing config uses unit + scale format
46
+ */
47
+ export declare function isSpacingWithUnit(spacing: SpacingConfig | Record<string | number, string>): spacing is SpacingConfig;
48
+
49
+ /**
50
+ * Additional named spacing values
51
+ */
52
+ export declare const namedSpacing: Record<string, string>;
53
+
54
+ /**
55
+ * Resolve spacing config to final key-value pairs
56
+ */
57
+ export declare function resolveSpacing(spacing: SpacingConfig | Record<string | number, string>): Record<string | number, string>;
58
+
59
+ /**
60
+ * Flex UI Configuration
61
+ *
62
+ * Consumers can create a flex.config.ts file to customize
63
+ * breakpoints, spacing, and output path for CSS generation.
64
+ */
65
+ export declare interface SpacingConfig {
66
+ /**
67
+ * Base spacing unit (e.g., "4px", "0.25rem", "1rem")
68
+ * Each spacing step will be a multiple of this value
69
+ */
70
+ unit: string;
71
+ /**
72
+ * Multipliers for each spacing step
73
+ * @example [0, 1, 2, 3, 4, 6, 8, 12, 16] generates 0, 4px, 8px, 12px, ...
74
+ */
75
+ scale: number[];
76
+ }
77
+
78
+ export { }
package/dist/config.js ADDED
@@ -0,0 +1,42 @@
1
+ function a(t) {
2
+ return "unit" in t && "scale" in t;
3
+ }
4
+ function f(t) {
5
+ if (!a(t))
6
+ return t;
7
+ const { unit: i, scale: u } = t, n = i.match(/^([\d.]+)(.+)$/);
8
+ if (!n)
9
+ throw new Error(
10
+ `Invalid spacing unit: ${i}. Expected format like "4px" or "0.25rem"`
11
+ );
12
+ const r = parseFloat(n[1]), s = n[2], o = {};
13
+ for (const e of u) {
14
+ const c = r * e;
15
+ o[e] = c === 0 ? "0" : `${c}${s}`;
16
+ }
17
+ return o;
18
+ }
19
+ const l = {
20
+ unit: "8px",
21
+ scale: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
22
+ }, p = {
23
+ fourth: "2px",
24
+ half: "4px"
25
+ }, x = {
26
+ breakpoints: {
27
+ xs: 480,
28
+ sm: 600,
29
+ md: 720,
30
+ lg: 960,
31
+ xl: 1200
32
+ },
33
+ spacing: l,
34
+ output: "./flex-ui.css"
35
+ };
36
+ export {
37
+ x as defaultConfig,
38
+ l as defaultSpacingConfig,
39
+ a as isSpacingWithUnit,
40
+ p as namedSpacing,
41
+ f as resolveSpacing
42
+ };