@awaitio/theme-default 0.0.0-stage → 0.0.1
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/LICENSE +64 -0
- package/dist/blocks/Button.d.ts +4 -0
- package/dist/blocks/Button.d.ts.map +1 -0
- package/dist/blocks/Button.js +9 -0
- package/dist/blocks/Card.d.ts +4 -0
- package/dist/blocks/Card.d.ts.map +1 -0
- package/dist/blocks/Card.js +8 -0
- package/dist/blocks/ChoiceList.d.ts +4 -0
- package/dist/blocks/ChoiceList.d.ts.map +1 -0
- package/dist/blocks/ChoiceList.js +26 -0
- package/dist/blocks/Field.d.ts +4 -0
- package/dist/blocks/Field.d.ts.map +1 -0
- package/dist/blocks/Field.js +13 -0
- package/dist/blocks/Heading.d.ts +4 -0
- package/dist/blocks/Heading.d.ts.map +1 -0
- package/dist/blocks/Heading.js +9 -0
- package/dist/blocks/Hint.d.ts +4 -0
- package/dist/blocks/Hint.d.ts.map +1 -0
- package/dist/blocks/Hint.js +9 -0
- package/dist/blocks/Input.d.ts +4 -0
- package/dist/blocks/Input.d.ts.map +1 -0
- package/dist/blocks/Input.js +12 -0
- package/dist/blocks/Label.d.ts +4 -0
- package/dist/blocks/Label.d.ts.map +1 -0
- package/dist/blocks/Label.js +8 -0
- package/dist/blocks/Link.d.ts +4 -0
- package/dist/blocks/Link.d.ts.map +1 -0
- package/dist/blocks/Link.js +17 -0
- package/dist/blocks/Metadata.d.ts +4 -0
- package/dist/blocks/Metadata.d.ts.map +1 -0
- package/dist/blocks/Metadata.js +11 -0
- package/dist/blocks/RowMenu.d.ts +4 -0
- package/dist/blocks/RowMenu.d.ts.map +1 -0
- package/dist/blocks/RowMenu.js +41 -0
- package/dist/blocks/Select.d.ts +4 -0
- package/dist/blocks/Select.d.ts.map +1 -0
- package/dist/blocks/Select.js +15 -0
- package/dist/blocks/Table.d.ts +4 -0
- package/dist/blocks/Table.d.ts.map +1 -0
- package/dist/blocks/Table.js +51 -0
- package/dist/blocks/Textarea.d.ts +4 -0
- package/dist/blocks/Textarea.d.ts.map +1 -0
- package/dist/blocks/Textarea.js +12 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/defaultTheme.d.ts +17 -0
- package/dist/defaultTheme.d.ts.map +1 -0
- package/dist/defaultTheme.js +36 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/ui/ui.css +1 -0
- package/dist/ui/ui.js +1 -0
- package/package.json +37 -4
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# AwaitIO License
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 Orukami s.r.o., Rybná 716/24, 110 00 Praha 1, Czech Republic, company ID 64049159, registered in the Commercial Register kept by the Municipal Court in Prague, section C, file 74046 (the "Licensor")
|
|
4
|
+
|
|
5
|
+
The source code of AwaitIO is public. Whether you can use it for free depends on how many people use it: small teams use AwaitIO for free, including commercially, while for-profit organizations with more users need a Company License. This keeps AwaitIO free for most people and funds its development.
|
|
6
|
+
|
|
7
|
+
This license covers everything in this repository, the package `awaitio` and every package published by the Licensor under the `@awaitio` scope on npm, now or in the future, such as `@awaitio/input-text`, `@awaitio/input-textarea` and `@awaitio/input-datetime` (together, "AwaitIO").
|
|
8
|
+
|
|
9
|
+
## Users
|
|
10
|
+
|
|
11
|
+
A "user" is a person who uses an application built with AwaitIO, whether it runs locally or is deployed: an employee, a contractor or anyone else who opens it, runs its actions or answers them. What counts is the number of real people, not the number of logins: several people sharing one login are several users. Count each person once across all of your organization's AwaitIO applications and environments.
|
|
12
|
+
|
|
13
|
+
## Free License
|
|
14
|
+
|
|
15
|
+
### Who is eligible
|
|
16
|
+
|
|
17
|
+
You may use AwaitIO for free if you are:
|
|
18
|
+
|
|
19
|
+
- an individual or a for-profit organization with up to 3 users;
|
|
20
|
+
- a non-profit or not-for-profit organization, or an educational institution; or
|
|
21
|
+
- evaluating whether AwaitIO fits your needs, and not yet using it commercially.
|
|
22
|
+
|
|
23
|
+
### What you may do
|
|
24
|
+
|
|
25
|
+
If you are eligible, you are granted permission, free of charge, to:
|
|
26
|
+
|
|
27
|
+
- use AwaitIO, commercially or not, including in production;
|
|
28
|
+
- build applications and internal tools with AwaitIO, for yourself and for your clients; and
|
|
29
|
+
- modify AwaitIO for your own use, or to contribute fixes and improvements back to AwaitIO.
|
|
30
|
+
|
|
31
|
+
## Company License
|
|
32
|
+
|
|
33
|
+
A for-profit organization with more than 3 users needs a Company License to use AwaitIO, priced by the number of users (see the pricing in the README). It allows the same use as the Free License. To get one, write to p.homoky@gmail.com.
|
|
34
|
+
|
|
35
|
+
Eligibility is decided by the organization that uses AwaitIO. If you build tools with AwaitIO for a client and the client runs them, the client's users count and the client needs a Company License unless it is eligible for the Free License itself.
|
|
36
|
+
|
|
37
|
+
## Same software, honor system
|
|
38
|
+
|
|
39
|
+
The Free License and the Company License cover exactly the same software. AwaitIO has no paid features, no license keys, no usage limits and no telemetry, and it never checks which license you have. The licensing works on trust: if your organization needs a Company License, get one.
|
|
40
|
+
|
|
41
|
+
## What nobody may do
|
|
42
|
+
|
|
43
|
+
Whatever your license, without a separate written agreement with the Licensor you may not:
|
|
44
|
+
|
|
45
|
+
1. copy or modify AwaitIO in order to sell, rent, license, relicense or sublicense AwaitIO itself or your own derivative or fork of it;
|
|
46
|
+
2. offer AwaitIO, or a derivative or fork of it, to third parties as a product or service that competes with AwaitIO;
|
|
47
|
+
3. offer to third parties a commercial hosted or managed service built on AwaitIO, such as a dashboard, cloud, monitoring or management service for applications that use AwaitIO; or
|
|
48
|
+
4. sell or license to third parties components, plugins or extensions made for AwaitIO.
|
|
49
|
+
|
|
50
|
+
Building applications with AwaitIO, running them and handing them over to your clients is none of the above.
|
|
51
|
+
|
|
52
|
+
## Changes to this license
|
|
53
|
+
|
|
54
|
+
The Licensor may change this license, including its prices and eligibility, at any time. A change applies to the versions of AwaitIO released after it; each version is governed by the license included with that version.
|
|
55
|
+
|
|
56
|
+
If you do not agree with the license of a newer version, you may keep using the versions you already have under the license they came with, but you may not upgrade to a version released under the license you do not agree with. Installing or using a newer version means you accept its license.
|
|
57
|
+
|
|
58
|
+
## Warranty
|
|
59
|
+
|
|
60
|
+
AwaitIO is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the Licensor or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with AwaitIO or the use of or other dealings in AwaitIO.
|
|
61
|
+
|
|
62
|
+
## Support
|
|
63
|
+
|
|
64
|
+
Support is provided on a best-effort basis through GitHub issues. Company License holders get priority.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/blocks/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAUlC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Button = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const Button = ({ variant = 'primary', className, type = 'button', ...props }) => {
|
|
6
|
+
const variantClassName = variant === 'primary' ? 'bg-gray-900 text-white hover:bg-gray-700' : 'border border-gray-300 bg-white text-gray-900 hover:bg-gray-100';
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)("button", { type: type, className: ['rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50', variantClassName, className].filter(Boolean).join(' '), ...props }));
|
|
8
|
+
};
|
|
9
|
+
exports.Button = Button;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/blocks/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAE9B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Card = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const Card = ({ children }) => {
|
|
6
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "rounded-lg border border-gray-200 bg-white p-6 shadow-sm", children: children });
|
|
7
|
+
};
|
|
8
|
+
exports.Card = Card;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChoiceList.d.ts","sourceRoot":"","sources":["../../src/blocks/ChoiceList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA8C1C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChoiceList = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
// Options as a list of cards to pick from, for a short list; a long one reads better as a Select.
|
|
7
|
+
const ChoiceList = ({ choices, mode, value, onChange, disabled }) => {
|
|
8
|
+
const name = (0, ui_1.useFieldId)();
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)("div", { role: mode === 'single' ? 'radiogroup' : 'group', id: name, className: "flex flex-col gap-2", children: choices.map((choice) => {
|
|
10
|
+
const isChosen = value.includes(choice.value);
|
|
11
|
+
return ((0, jsx_runtime_1.jsxs)("label", { className: ['flex cursor-pointer items-start gap-3 rounded-md border bg-white px-3 py-2.5 text-sm', isChosen && 'border-gray-900', !isChosen && 'border-gray-300 hover:border-gray-400']
|
|
12
|
+
.filter(Boolean)
|
|
13
|
+
.join(' '), children: [(0, jsx_runtime_1.jsx)("input", { type: mode === 'single' ? 'radio' : 'checkbox', name: name, checked: isChosen, disabled: disabled, onChange: () => {
|
|
14
|
+
if (mode === 'single') {
|
|
15
|
+
onChange([choice.value]);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
onChange(isChosen
|
|
19
|
+
? value.filter((chosen) => {
|
|
20
|
+
return chosen !== choice.value;
|
|
21
|
+
})
|
|
22
|
+
: [...value, choice.value]);
|
|
23
|
+
}, className: "mt-0.5 accent-gray-900" }), (0, jsx_runtime_1.jsxs)("span", { className: "flex flex-col gap-0.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: choice.label }), choice.description && (0, jsx_runtime_1.jsx)("span", { className: "text-gray-500", children: choice.description })] })] }, choice.value));
|
|
24
|
+
}) }));
|
|
25
|
+
};
|
|
26
|
+
exports.ChoiceList = ChoiceList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/blocks/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAS,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAiBhC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Field = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
// Label, control, help text and error of one form field. The SDK wraps every component in it unless the component
|
|
8
|
+
// sets `wrap: false`; a component drawing its own layout can use it directly too.
|
|
9
|
+
const Field = ({ label, helpText, error, children }) => {
|
|
10
|
+
const id = (0, react_1.useId)();
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(ui_1.FieldContext.Provider, { value: id, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [(0, jsx_runtime_1.jsx)(ui_1.Label, { htmlFor: id, children: label }), children, helpText && (0, jsx_runtime_1.jsx)(ui_1.Hint, { children: helpText }), error && ((0, jsx_runtime_1.jsx)("p", { role: "alert", className: "text-xs text-red-600", children: error }))] }) }));
|
|
12
|
+
};
|
|
13
|
+
exports.Field = Field;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/blocks/Heading.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CAOpC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Heading = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// The title of one block of a page, e.g. above a table.
|
|
6
|
+
const Heading = ({ children, description }) => {
|
|
7
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-base font-semibold text-gray-900", children: children }), description && (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-500", children: description })] }));
|
|
8
|
+
};
|
|
9
|
+
exports.Heading = Heading;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Hint.d.ts","sourceRoot":"","sources":["../../src/blocks/Hint.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAE9B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Hint = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// Small secondary text under a control, e.g. the time zone of a date field.
|
|
6
|
+
const Hint = ({ children }) => {
|
|
7
|
+
return (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-gray-500", children: children });
|
|
8
|
+
};
|
|
9
|
+
exports.Hint = Hint;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/blocks/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAahC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Input = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const Input = ({ value, onChange, type = 'text', ...props }) => {
|
|
8
|
+
return ((0, jsx_runtime_1.jsx)("input", { ...props, id: (0, ui_1.useFieldId)(), type: type, value: value, onChange: (event) => {
|
|
9
|
+
onChange(event.target.value);
|
|
10
|
+
}, className: constants_1.constants.CONTROL_CLASS_NAME }));
|
|
11
|
+
};
|
|
12
|
+
exports.Input = Input;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.d.ts","sourceRoot":"","sources":["../../src/blocks/Label.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAMhC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Label = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const Label = ({ htmlFor, children }) => {
|
|
6
|
+
return ((0, jsx_runtime_1.jsx)("label", { htmlFor: htmlFor, className: "text-sm font-medium", children: children }));
|
|
7
|
+
};
|
|
8
|
+
exports.Label = Label;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/blocks/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAiB9B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Link = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
// A link to another page of the AwaitIO UI, e.g. an action with params. A plain click stays in the app; a click with
|
|
7
|
+
// a modifier key opens a new tab as usual.
|
|
8
|
+
const Link = ({ href, children, className = 'text-blue-600 underline-offset-2 hover:text-blue-800 hover:underline' }) => {
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)("a", { href: href, className: className, onClick: (event) => {
|
|
10
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.button !== 0) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
event.preventDefault();
|
|
14
|
+
(0, ui_1.navigateTo)(href);
|
|
15
|
+
}, children: children }));
|
|
16
|
+
};
|
|
17
|
+
exports.Link = Link;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Metadata.d.ts","sourceRoot":"","sources":["../../src/blocks/Metadata.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CActC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Metadata = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// Label and value tiles in a grid, e.g. "Total accounts 542" above a table.
|
|
6
|
+
const Metadata = ({ items }) => {
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)("dl", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4", children: items.map((item) => {
|
|
8
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1 rounded-lg border border-gray-200 bg-white px-4 py-3", children: [(0, jsx_runtime_1.jsx)("dt", { className: "text-sm text-gray-500", children: item.label }), (0, jsx_runtime_1.jsx)("dd", { className: "text-2xl font-semibold text-gray-900", children: item.value }), item.description && (0, jsx_runtime_1.jsx)("dd", { className: "text-xs text-gray-500", children: item.description })] }, item.label));
|
|
9
|
+
}) }));
|
|
10
|
+
};
|
|
11
|
+
exports.Metadata = Metadata;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowMenu.d.ts","sourceRoot":"","sources":["../../src/blocks/RowMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAS7D,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CA6DpC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RowMenu = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
// The "…" button at the end of a table row with links for that row. The list is fixed to the window, so the table's
|
|
8
|
+
// sideways scroll box cannot cut it off at the last rows; it closes on a click outside, Escape or scrolling.
|
|
9
|
+
const RowMenu = ({ items }) => {
|
|
10
|
+
const [position, setPosition] = (0, react_1.useState)(null);
|
|
11
|
+
const root = (0, react_1.useRef)(null);
|
|
12
|
+
(0, react_1.useEffect)(() => {
|
|
13
|
+
if (!position) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const close = (event) => {
|
|
17
|
+
const isInside = event.type === 'mousedown' && root.current?.contains(event.target);
|
|
18
|
+
const isOtherKey = event instanceof KeyboardEvent && event.key !== 'Escape';
|
|
19
|
+
if (!isInside && !isOtherKey) {
|
|
20
|
+
setPosition(null);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
document.addEventListener('mousedown', close);
|
|
24
|
+
document.addEventListener('keydown', close);
|
|
25
|
+
window.addEventListener('scroll', close, true);
|
|
26
|
+
window.addEventListener('resize', close);
|
|
27
|
+
return () => {
|
|
28
|
+
document.removeEventListener('mousedown', close);
|
|
29
|
+
document.removeEventListener('keydown', close);
|
|
30
|
+
window.removeEventListener('scroll', close, true);
|
|
31
|
+
window.removeEventListener('resize', close);
|
|
32
|
+
};
|
|
33
|
+
}, [position]);
|
|
34
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: root, className: "flex justify-end", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "Row actions", "aria-expanded": position !== null, onClick: (event) => {
|
|
35
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
36
|
+
setPosition(position ? null : { top: rect.bottom + 4, right: window.innerWidth - rect.right });
|
|
37
|
+
}, className: "rounded-md p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-900", children: (0, jsx_runtime_1.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 20 20", className: "h-5 w-5 fill-current", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "10", r: "1.5" }), (0, jsx_runtime_1.jsx)("circle", { cx: "10", cy: "10", r: "1.5" }), (0, jsx_runtime_1.jsx)("circle", { cx: "15.5", cy: "10", r: "1.5" })] }) }), position && ((0, jsx_runtime_1.jsx)("div", { style: { top: position.top, right: position.right }, className: "fixed z-20 flex min-w-40 flex-col rounded-lg border border-gray-200 bg-white py-1 shadow-lg", children: items.map((item) => {
|
|
38
|
+
return ((0, jsx_runtime_1.jsx)(ui_1.Link, { href: item.href, className: "px-3 py-2 text-sm whitespace-nowrap text-gray-700 hover:bg-gray-50 hover:text-gray-900", children: item.label }, item.label));
|
|
39
|
+
}) }))] }));
|
|
40
|
+
};
|
|
41
|
+
exports.RowMenu = RowMenu;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/blocks/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAwBlC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Select = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
// A native drop-down for one of many options.
|
|
8
|
+
const Select = ({ choices, value, onChange, placeholder = 'Choose…', disabled, autoFocus }) => {
|
|
9
|
+
return ((0, jsx_runtime_1.jsxs)("select", { id: (0, ui_1.useFieldId)(), value: value, disabled: disabled, autoFocus: autoFocus, onChange: (event) => {
|
|
10
|
+
onChange(event.target.value);
|
|
11
|
+
}, className: constants_1.constants.CONTROL_CLASS_NAME, children: [(0, jsx_runtime_1.jsx)("option", { value: "", disabled: true, children: placeholder }), choices.map((choice) => {
|
|
12
|
+
return ((0, jsx_runtime_1.jsx)("option", { value: choice.value, children: choice.label }, choice.value));
|
|
13
|
+
})] }));
|
|
14
|
+
};
|
|
15
|
+
exports.Select = Select;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/blocks/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI1C,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAuIhC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Table = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
// A data table for layouts: an optional filter, a header row, one row per record with an optional "…" menu, and a pager.
|
|
8
|
+
// Filtering and paging happen in the browser, on the rows the page sent.
|
|
9
|
+
const Table = ({ columns, rows, pageSize = 20, filterable = true, emptyText = 'Nothing to show.', selection }) => {
|
|
10
|
+
const [filter, setFilter] = (0, react_1.useState)('');
|
|
11
|
+
const [page, setPage] = (0, react_1.useState)(0);
|
|
12
|
+
const query = filter.trim().toLowerCase();
|
|
13
|
+
const matching = query
|
|
14
|
+
? rows.filter((row) => {
|
|
15
|
+
return row.searchText.toLowerCase().includes(query);
|
|
16
|
+
})
|
|
17
|
+
: rows;
|
|
18
|
+
const pageCount = Math.max(1, Math.ceil(matching.length / pageSize));
|
|
19
|
+
const current = Math.min(page, pageCount - 1);
|
|
20
|
+
const shown = matching.slice(current * pageSize, (current + 1) * pageSize);
|
|
21
|
+
const hasMenu = rows.some((row) => {
|
|
22
|
+
return (row.menu ?? []).length > 0;
|
|
23
|
+
});
|
|
24
|
+
const hasToolbar = filterable || matching.length > pageSize;
|
|
25
|
+
const pagerButton = 'rounded-md border border-gray-200 px-2.5 py-1 text-xs font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40';
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "rounded-lg border border-gray-200 bg-white", children: [hasToolbar && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-gray-200 px-3 py-2", children: [filterable ? ((0, jsx_runtime_1.jsx)("input", { type: "search", value: filter, placeholder: "Filter", "aria-label": "Filter rows", onChange: (event) => {
|
|
27
|
+
setFilter(event.target.value);
|
|
28
|
+
setPage(0);
|
|
29
|
+
}, className: "w-full max-w-56 rounded-md border border-gray-300 bg-white px-3 py-1 text-sm shadow-sm focus:border-gray-900 focus:outline-none" })) : ((0, jsx_runtime_1.jsx)("span", {})), matching.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [(0, jsx_runtime_1.jsxs)("span", { children: [current * pageSize + 1, "\u2013", Math.min((current + 1) * pageSize, matching.length), " of ", matching.length] }), matching.length > pageSize && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { type: "button", disabled: current === 0, onClick: () => {
|
|
30
|
+
setPage(current - 1);
|
|
31
|
+
}, className: pagerButton, children: "Prev" }), (0, jsx_runtime_1.jsx)("button", { type: "button", disabled: current >= pageCount - 1, onClick: () => {
|
|
32
|
+
setPage(current + 1);
|
|
33
|
+
}, className: pagerButton, children: "Next" })] }))] }))] })), shown.length === 0 ? ((0, jsx_runtime_1.jsx)("p", { className: "px-4 py-6 text-sm text-gray-500", children: query ? 'No rows match the filter.' : emptyText })) : ((0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-left text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { className: hasToolbar ? 'bg-gray-50' : 'bg-gray-50 [&_th:first-child]:rounded-tl-lg [&_th:last-child]:rounded-tr-lg', children: (0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-gray-200", children: [selection && (0, jsx_runtime_1.jsx)("th", { className: "w-10", "aria-label": "Selected" }), columns.map((column) => {
|
|
34
|
+
return ((0, jsx_runtime_1.jsx)("th", { className: "px-4 py-2.5 font-medium whitespace-nowrap text-gray-500", children: column.label }, column.key));
|
|
35
|
+
}), hasMenu && (0, jsx_runtime_1.jsx)("th", { className: "w-10", "aria-label": "Row actions" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: shown.map((row, rowIndex) => {
|
|
36
|
+
return ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-gray-100 last:border-0", children: [selection && row.id !== undefined && ((0, jsx_runtime_1.jsx)("td", { className: "py-2.5 pl-4", children: (0, jsx_runtime_1.jsx)("input", { type: selection.mode === 'single' ? 'radio' : 'checkbox', "aria-label": "Select row", checked: selection.selected.includes(row.id), disabled: selection.disabled, onChange: () => {
|
|
37
|
+
const id = row.id ?? -1;
|
|
38
|
+
const isSelected = selection.selected.includes(id);
|
|
39
|
+
selection.onChange(selection.mode === 'single'
|
|
40
|
+
? [id]
|
|
41
|
+
: isSelected
|
|
42
|
+
? selection.selected.filter((selected) => {
|
|
43
|
+
return selected !== id;
|
|
44
|
+
})
|
|
45
|
+
: [...selection.selected, id]);
|
|
46
|
+
}, className: "accent-gray-900" }) })), columns.map((column) => {
|
|
47
|
+
return ((0, jsx_runtime_1.jsx)("td", { className: "px-4 py-2.5", children: row.cells[column.key] }, column.key));
|
|
48
|
+
}), hasMenu && (0, jsx_runtime_1.jsx)("td", { className: "px-2 py-1.5", children: row.menu && row.menu.length > 0 && (0, jsx_runtime_1.jsx)(ui_1.RowMenu, { items: row.menu }) })] }, row.id ?? current * pageSize + rowIndex));
|
|
49
|
+
}) })] }) }))] }));
|
|
50
|
+
};
|
|
51
|
+
exports.Table = Table;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../../src/blocks/Textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAYtC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Textarea = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ui_1 = require("awaitio/ui");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const Textarea = ({ value, onChange, ...props }) => {
|
|
8
|
+
return ((0, jsx_runtime_1.jsx)("textarea", { ...props, id: (0, ui_1.useFieldId)(), value: value, onChange: (event) => {
|
|
9
|
+
onChange(event.target.value);
|
|
10
|
+
}, className: constants_1.constants.CONTROL_CLASS_NAME }));
|
|
11
|
+
};
|
|
12
|
+
exports.Textarea = Textarea;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;IAEpB,kBAAkB;CACnB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.constants = void 0;
|
|
4
|
+
exports.constants = {
|
|
5
|
+
// One look for every text-like control, so all inputs of the theme match.
|
|
6
|
+
CONTROL_CLASS_NAME: 'w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm focus:border-gray-900 focus:outline-none disabled:bg-gray-100',
|
|
7
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const defaultTheme: import("awaitio").ThemeBlockRefs<{
|
|
2
|
+
Button: import("react").FC<import("awaitio/ui").ButtonProps>;
|
|
3
|
+
Card: import("react").FC<import("awaitio/ui").CardProps>;
|
|
4
|
+
ChoiceList: import("react").FC<import("awaitio/ui").ChoiceListProps>;
|
|
5
|
+
Field: import("react").FC<import("awaitio/ui").FieldProps>;
|
|
6
|
+
Heading: import("react").FC<import("awaitio/ui").HeadingProps>;
|
|
7
|
+
Hint: import("react").FC<import("awaitio/ui").HintProps>;
|
|
8
|
+
Input: import("react").FC<import("awaitio/ui").InputProps>;
|
|
9
|
+
Label: import("react").FC<import("awaitio/ui").LabelProps>;
|
|
10
|
+
Link: import("react").FC<import("awaitio/ui").LinkProps>;
|
|
11
|
+
Metadata: import("react").FC<import("awaitio/ui").MetadataProps>;
|
|
12
|
+
RowMenu: import("react").FC<import("awaitio/ui").RowMenuProps>;
|
|
13
|
+
Select: import("react").FC<import("awaitio/ui").SelectProps>;
|
|
14
|
+
Table: import("react").FC<import("awaitio/ui").TableProps>;
|
|
15
|
+
Textarea: import("react").FC<import("awaitio/ui").TextareaProps>;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=defaultTheme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultTheme.d.ts","sourceRoot":"","sources":["../src/defaultTheme.tsx"],"names":[],"mappings":"AAkBA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;EAevB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultTheme = void 0;
|
|
4
|
+
const awaitio_1 = require("awaitio");
|
|
5
|
+
const Button_1 = require("./blocks/Button");
|
|
6
|
+
const Card_1 = require("./blocks/Card");
|
|
7
|
+
const ChoiceList_1 = require("./blocks/ChoiceList");
|
|
8
|
+
const Field_1 = require("./blocks/Field");
|
|
9
|
+
const Heading_1 = require("./blocks/Heading");
|
|
10
|
+
const Hint_1 = require("./blocks/Hint");
|
|
11
|
+
const Input_1 = require("./blocks/Input");
|
|
12
|
+
const Label_1 = require("./blocks/Label");
|
|
13
|
+
const Link_1 = require("./blocks/Link");
|
|
14
|
+
const Metadata_1 = require("./blocks/Metadata");
|
|
15
|
+
const RowMenu_1 = require("./blocks/RowMenu");
|
|
16
|
+
const Select_1 = require("./blocks/Select");
|
|
17
|
+
const Table_1 = require("./blocks/Table");
|
|
18
|
+
const Textarea_1 = require("./blocks/Textarea");
|
|
19
|
+
// The look AwaitIO ships with: every block. Replace single ones with blocks of your own theme:
|
|
20
|
+
// theme: { ...defaultTheme, Label: myTheme.Label }.
|
|
21
|
+
exports.defaultTheme = (0, awaitio_1.defineTheme)({
|
|
22
|
+
Button: Button_1.Button,
|
|
23
|
+
Card: Card_1.Card,
|
|
24
|
+
ChoiceList: ChoiceList_1.ChoiceList,
|
|
25
|
+
Field: Field_1.Field,
|
|
26
|
+
Heading: Heading_1.Heading,
|
|
27
|
+
Hint: Hint_1.Hint,
|
|
28
|
+
Input: Input_1.Input,
|
|
29
|
+
Label: Label_1.Label,
|
|
30
|
+
Link: Link_1.Link,
|
|
31
|
+
Metadata: Metadata_1.Metadata,
|
|
32
|
+
RowMenu: RowMenu_1.RowMenu,
|
|
33
|
+
Select: Select_1.Select,
|
|
34
|
+
Table: Table_1.Table,
|
|
35
|
+
Textarea: Textarea_1.Textarea,
|
|
36
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultTheme = void 0;
|
|
4
|
+
var defaultTheme_1 = require("./defaultTheme");
|
|
5
|
+
Object.defineProperty(exports, "defaultTheme", { enumerable: true, get: function () { return defaultTheme_1.defaultTheme; } });
|
package/dist/ui/ui.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--color-red-600:oklch(57.7% .245 27.325);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.fixed{position:fixed}.z-20{z-index:20}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.block{display:block}.flex{display:flex}.grid{display:grid}.table{display:table}.h-5{height:calc(var(--spacing) * 5)}.w-5{width:calc(var(--spacing) * 5)}.w-10{width:calc(var(--spacing) * 10)}.w-full{width:100%}.max-w-56{max-width:calc(var(--spacing) * 56)}.min-w-40{min-width:calc(var(--spacing) * 40)}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.overflow-x-auto{overflow-x:auto}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-900{border-color:var(--color-gray-900)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.p-1{padding:var(--spacing)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-left{text-align:left}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-blue-600{color:var(--color-blue-600)}.text-gray-500{color:var(--color-gray-500)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.underline-offset-2{text-underline-offset:2px}.accent-gray-900{accent-color:var(--color-gray-900)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media(hover:hover){.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-gray-900:focus{border-color:var(--color-gray-900)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-100:disabled{background-color:var(--color-gray-100)}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.\[\&_th\:first-child\]\:rounded-tl-lg th:first-child{border-top-left-radius:var(--radius-lg)}.\[\&_th\:last-child\]\:rounded-tr-lg th:last-child{border-top-right-radius:var(--radius-lg)}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
|
package/dist/ui/ui.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var awaitioComponent=(function(m,e,c,y){"use strict";const E=r=>Object.fromEntries(Object.entries(r).map(([t,a])=>[t,{kind:"awaitio-theme-block",name:t,component:a,uiDirectory:null}])),A=({variant:r="primary",className:t,type:a="button",...s})=>{const n=r==="primary"?"bg-gray-900 text-white hover:bg-gray-700":"border border-gray-300 bg-white text-gray-900 hover:bg-gray-100";return e.jsx("button",{type:a,className:["rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",n,t].filter(Boolean).join(" "),...s})},O=({children:r})=>e.jsx("div",{className:"rounded-lg border border-gray-200 bg-white p-6 shadow-sm",children:r}),T=({choices:r,mode:t,value:a,onChange:s,disabled:n})=>{const o=c.useFieldId();return e.jsx("div",{role:t==="single"?"radiogroup":"group",id:o,className:"flex flex-col gap-2",children:r.map(l=>{const p=a.includes(l.value);return e.jsxs("label",{className:["flex cursor-pointer items-start gap-3 rounded-md border bg-white px-3 py-2.5 text-sm",p&&"border-gray-900",!p&&"border-gray-300 hover:border-gray-400"].filter(Boolean).join(" "),children:[e.jsx("input",{type:t==="single"?"radio":"checkbox",name:o,checked:p,disabled:n,onChange:()=>{if(t==="single"){s([l.value]);return}s(p?a.filter(f=>f!==l.value):[...a,l.value])},className:"mt-0.5 accent-gray-900"}),e.jsxs("span",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"font-medium",children:l.label}),l.description&&e.jsx("span",{className:"text-gray-500",children:l.description})]})]},l.value)})})},k=({label:r,helpText:t,error:a,children:s})=>{const n=y.useId();return e.jsx(c.FieldContext.Provider,{value:n,children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(c.Label,{htmlFor:n,children:r}),s,t&&e.jsx(c.Hint,{children:t}),a&&e.jsx("p",{role:"alert",className:"text-xs text-red-600",children:a})]})})},S=({children:r,description:t})=>e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("h2",{className:"text-base font-semibold text-gray-900",children:r}),t&&e.jsx("p",{className:"text-sm text-gray-500",children:t})]}),M=({children:r})=>e.jsx("p",{className:"text-xs text-gray-500",children:r}),x={CONTROL_CLASS_NAME:"w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm focus:border-gray-900 focus:outline-none disabled:bg-gray-100"},U=({value:r,onChange:t,type:a="text",...s})=>e.jsx("input",{...s,id:c.useFieldId(),type:a,value:r,onChange:n=>{t(n.target.value)},className:x.CONTROL_CLASS_NAME}),j=({htmlFor:r,children:t})=>e.jsx("label",{htmlFor:r,className:"text-sm font-medium",children:t}),F=({href:r,children:t,className:a="text-blue-600 underline-offset-2 hover:text-blue-800 hover:underline"})=>e.jsx("a",{href:r,className:a,onClick:s=>{s.metaKey||s.ctrlKey||s.shiftKey||s.button!==0||(s.preventDefault(),c.navigateTo(r))},children:t}),H=({items:r})=>e.jsx("dl",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4",children:r.map(t=>e.jsxs("div",{className:"flex flex-col gap-1 rounded-lg border border-gray-200 bg-white px-4 py-3",children:[e.jsx("dt",{className:"text-sm text-gray-500",children:t.label}),e.jsx("dd",{className:"text-2xl font-semibold text-gray-900",children:t.value}),t.description&&e.jsx("dd",{className:"text-xs text-gray-500",children:t.description})]},t.label))}),B=({items:r})=>{const[t,a]=y.useState(null),s=y.useRef(null);return y.useEffect(()=>{if(!t)return;const n=o=>{const l=o.type==="mousedown"&&s.current?.contains(o.target),p=o instanceof KeyboardEvent&&o.key!=="Escape";!l&&!p&&a(null)};return document.addEventListener("mousedown",n),document.addEventListener("keydown",n),window.addEventListener("scroll",n,!0),window.addEventListener("resize",n),()=>{document.removeEventListener("mousedown",n),document.removeEventListener("keydown",n),window.removeEventListener("scroll",n,!0),window.removeEventListener("resize",n)}},[t]),e.jsxs("div",{ref:s,className:"flex justify-end",children:[e.jsx("button",{type:"button","aria-label":"Row actions","aria-expanded":t!==null,onClick:n=>{const o=n.currentTarget.getBoundingClientRect();a(t?null:{top:o.bottom+4,right:window.innerWidth-o.right})},className:"rounded-md p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-900",children:e.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 20 20",className:"h-5 w-5 fill-current",children:[e.jsx("circle",{cx:"4.5",cy:"10",r:"1.5"}),e.jsx("circle",{cx:"10",cy:"10",r:"1.5"}),e.jsx("circle",{cx:"15.5",cy:"10",r:"1.5"})]})}),t&&e.jsx("div",{style:{top:t.top,right:t.right},className:"fixed z-20 flex min-w-40 flex-col rounded-lg border border-gray-200 bg-white py-1 shadow-lg",children:r.map(n=>e.jsx(c.Link,{href:n.href,className:"px-3 py-2 text-sm whitespace-nowrap text-gray-700 hover:bg-gray-50 hover:text-gray-900",children:n.label},n.label))})]})},K=({choices:r,value:t,onChange:a,placeholder:s="Choose…",disabled:n,autoFocus:o})=>e.jsxs("select",{id:c.useFieldId(),value:t,disabled:n,autoFocus:o,onChange:l=>{a(l.target.value)},className:x.CONTROL_CLASS_NAME,children:[e.jsx("option",{value:"",disabled:!0,children:s}),r.map(l=>e.jsx("option",{value:l.value,children:l.label},l.value))]}),P=({columns:r,rows:t,pageSize:a=20,filterable:s=!0,emptyText:n="Nothing to show.",selection:o})=>{const[l,p]=y.useState(""),[f,w]=y.useState(0),N=l.trim().toLowerCase(),g=N?t.filter(d=>d.searchText.toLowerCase().includes(N)):t,v=Math.max(1,Math.ceil(g.length/a)),h=Math.min(f,v-1),C=g.slice(h*a,(h+1)*a),L=t.some(d=>(d.menu??[]).length>0),I=s||g.length>a,_="rounded-md border border-gray-200 px-2.5 py-1 text-xs font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40";return e.jsxs("div",{className:"rounded-lg border border-gray-200 bg-white",children:[I&&e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-b border-gray-200 px-3 py-2",children:[s?e.jsx("input",{type:"search",value:l,placeholder:"Filter","aria-label":"Filter rows",onChange:d=>{p(d.target.value),w(0)},className:"w-full max-w-56 rounded-md border border-gray-300 bg-white px-3 py-1 text-sm shadow-sm focus:border-gray-900 focus:outline-none"}):e.jsx("span",{}),g.length>0&&e.jsxs("div",{className:"flex items-center gap-2 text-xs text-gray-500",children:[e.jsxs("span",{children:[h*a+1,"–",Math.min((h+1)*a,g.length)," of ",g.length]}),g.length>a&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",disabled:h===0,onClick:()=>{w(h-1)},className:_,children:"Prev"}),e.jsx("button",{type:"button",disabled:h>=v-1,onClick:()=>{w(h+1)},className:_,children:"Next"})]})]})]}),C.length===0?e.jsx("p",{className:"px-4 py-6 text-sm text-gray-500",children:N?"No rows match the filter.":n}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-left text-sm",children:[e.jsx("thead",{className:I?"bg-gray-50":"bg-gray-50 [&_th:first-child]:rounded-tl-lg [&_th:last-child]:rounded-tr-lg",children:e.jsxs("tr",{className:"border-b border-gray-200",children:[o&&e.jsx("th",{className:"w-10","aria-label":"Selected"}),r.map(d=>e.jsx("th",{className:"px-4 py-2.5 font-medium whitespace-nowrap text-gray-500",children:d.label},d.key)),L&&e.jsx("th",{className:"w-10","aria-label":"Row actions"})]})}),e.jsx("tbody",{children:C.map((d,J)=>e.jsxs("tr",{className:"border-b border-gray-100 last:border-0",children:[o&&d.id!==void 0&&e.jsx("td",{className:"py-2.5 pl-4",children:e.jsx("input",{type:o.mode==="single"?"radio":"checkbox","aria-label":"Select row",checked:o.selected.includes(d.id),disabled:o.disabled,onChange:()=>{const b=d.id??-1,Q=o.selected.includes(b);o.onChange(o.mode==="single"?[b]:Q?o.selected.filter(X=>X!==b):[...o.selected,b])},className:"accent-gray-900"})}),r.map(b=>e.jsx("td",{className:"px-4 py-2.5",children:d.cells[b.key]},b.key)),L&&e.jsx("td",{className:"px-2 py-1.5",children:d.menu&&d.menu.length>0&&e.jsx(c.RowMenu,{items:d.menu})})]},d.id??h*a+J))})]})})]})},W=({value:r,onChange:t,...a})=>e.jsx("textarea",{...a,id:c.useFieldId(),value:r,onChange:s=>{t(s.target.value)},className:x.CONTROL_CLASS_NAME}),u="__AWAITIO__",D=r=>{const t=window[u],a=document.currentScript,s=a instanceof HTMLScriptElement?a.dataset.type:void 0;if(!t||!s)throw new Error("A component UI script must be loaded by the AwaitIO UI.");t.registerComponent(s,r)},V=r=>{const t=window[u],a=document.currentScript,s=a instanceof HTMLScriptElement?a.dataset.type:void 0;if(!t||!s)throw new Error("A display component UI script must be loaded by the AwaitIO UI.");t.registerDisplay(s,r)},q=r=>{const t=window[u],a=document.currentScript,s=a instanceof HTMLScriptElement?a.dataset.type:void 0;if(!t||!s)throw new Error("A layout UI script must be loaded by the AwaitIO UI.");t.registerLayout(s,r)},G=r=>{const t=window[u],a=document.currentScript,s=a instanceof HTMLScriptElement?a.dataset.type:void 0;if(!t||!s)throw new Error("A theme UI script must be loaded by the AwaitIO UI.");t.registerTheme(s,r)},i=E({Button:A,Card:O,ChoiceList:T,Field:k,Heading:S,Hint:M,Input:U,Label:j,Link:F,Metadata:H,RowMenu:B,Select:K,Table:P,Textarea:W});return Object.values(i).every(r=>r&&r.kind==="awaitio-theme-block")?G({blocks:Object.fromEntries(Object.entries(i).map(([r,t])=>[r,t.component]))}):i.kind==="awaitio-layout"?q({component:i.component}):i.kind==="awaitio-display"?V({component:i.component}):D({component:i.component,initialValue:i.initialValue,wrap:i.wrap??!0}),m.defaultTheme=i,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m})({},__AWAITIO__.jsxRuntime,__AWAITIO__.ui,__AWAITIO__.React);
|
package/package.json
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awaitio/theme-default",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "The default look of AwaitIO: every block of awaitio/ui, with its styles.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && vite build",
|
|
13
|
+
"dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput & vite build --watch",
|
|
14
|
+
"tsc": "tsc --noEmit",
|
|
15
|
+
"lint": "eslint .",
|
|
16
|
+
"lint:fix": "eslint . --fix",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"release": "pnpm build && pnpm publish --access public --no-git-checks"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"awaitio": "workspace:^"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"react": "^19.1.0",
|
|
25
|
+
"zod": "3.22.4"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@tailwindcss/vite": "^4.1.0",
|
|
29
|
+
"@types/node": "^22.14.0",
|
|
30
|
+
"@types/react": "^19.1.0",
|
|
31
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
32
|
+
"@vitejs/plugin-react": "^5.0.0",
|
|
33
|
+
"awaitio": "workspace:*",
|
|
34
|
+
"tailwindcss": "^4.1.0",
|
|
35
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
36
|
+
"vite": "^7.1.0",
|
|
37
|
+
"vitest": "^3.2.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/README.md
DELETED