@_linked/shape-ui 2.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/.changeset/README.md +20 -0
- package/.changeset/config.json +14 -0
- package/.github/workflows/changeset-check.yml +44 -0
- package/.github/workflows/ci.yml +43 -0
- package/.github/workflows/publish.yml +158 -0
- package/CHANGELOG.md +30 -0
- package/README.md +35 -0
- package/lib/esm/backend.d.ts +0 -0
- package/lib/esm/backend.js +2 -0
- package/lib/esm/backend.js.map +1 -0
- package/lib/esm/components/AvatarEditor.d.ts +20 -0
- package/lib/esm/components/AvatarEditor.js +7 -0
- package/lib/esm/components/AvatarEditor.js.map +1 -0
- package/lib/esm/components/CheckboxEditor.d.ts +21 -0
- package/lib/esm/components/CheckboxEditor.js +44 -0
- package/lib/esm/components/CheckboxEditor.js.map +1 -0
- package/lib/esm/components/CheckboxEditor.module.css +6 -0
- package/lib/esm/components/DateEditor.d.ts +20 -0
- package/lib/esm/components/DateEditor.js +22 -0
- package/lib/esm/components/DateEditor.js.map +1 -0
- package/lib/esm/components/ImageValueEditor.module.css +3 -0
- package/lib/esm/components/RadioButtonEditor.d.ts +23 -0
- package/lib/esm/components/RadioButtonEditor.js +41 -0
- package/lib/esm/components/RadioButtonEditor.js.map +1 -0
- package/lib/esm/components/RadioButtonEditor.module.css +22 -0
- package/lib/esm/components/SelectEditor.d.ts +21 -0
- package/lib/esm/components/SelectEditor.js +30 -0
- package/lib/esm/components/SelectEditor.js.map +1 -0
- package/lib/esm/components/ShapeTable.module.css +394 -0
- package/lib/esm/components/SwitchEditor.d.ts +21 -0
- package/lib/esm/components/SwitchEditor.js +23 -0
- package/lib/esm/components/SwitchEditor.js.map +1 -0
- package/lib/esm/components/TextareaEditor.d.ts +23 -0
- package/lib/esm/components/TextareaEditor.js +15 -0
- package/lib/esm/components/TextareaEditor.js.map +1 -0
- package/lib/esm/components/TextfieldEditor.d.ts +24 -0
- package/lib/esm/components/TextfieldEditor.js +26 -0
- package/lib/esm/components/TextfieldEditor.js.map +1 -0
- package/lib/esm/components/ToggleEditor.d.ts +22 -0
- package/lib/esm/components/ToggleEditor.js +23 -0
- package/lib/esm/components/ToggleEditor.js.map +1 -0
- package/lib/esm/index.d.ts +10 -0
- package/lib/esm/index.js +15 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/ontologies/lincd-ui.d.ts +6 -0
- package/lib/esm/ontologies/lincd-ui.js +18 -0
- package/lib/esm/ontologies/lincd-ui.js.map +1 -0
- package/lib/esm/package.d.ts +3 -0
- package/lib/esm/package.js +4 -0
- package/lib/esm/package.js.map +1 -0
- package/package.json +75 -0
- package/tsconfig-cjs.json +8 -0
- package/tsconfig-esm.json +9 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
This package uses [changesets](https://github.com/changesets/changesets) for version management and publishing.
|
|
4
|
+
|
|
5
|
+
## Adding a changeset
|
|
6
|
+
|
|
7
|
+
When making a change that should trigger a new release, run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx changeset
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This generates a markdown file in `.changeset/` describing the change. Commit it with your PR.
|
|
14
|
+
|
|
15
|
+
On merge to `main`, the publish workflow either:
|
|
16
|
+
|
|
17
|
+
1. Creates (or updates) a **Release PR** that bumps the version + updates `CHANGELOG.md`, or
|
|
18
|
+
2. If the Release PR is already merged, publishes the new version to npm.
|
|
19
|
+
|
|
20
|
+
Changes that don't need a release (docs, CI config, tooling) can skip the changeset — the check is a warning, not a block.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": [
|
|
4
|
+
"@changesets/changelog-github",
|
|
5
|
+
{ "repo": "linked-cm/ui" }
|
|
6
|
+
],
|
|
7
|
+
"commit": false,
|
|
8
|
+
"fixed": [],
|
|
9
|
+
"linked": [],
|
|
10
|
+
"access": "public",
|
|
11
|
+
"baseBranch": "main",
|
|
12
|
+
"updateInternalDependencies": "patch",
|
|
13
|
+
"ignore": []
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Changeset Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
changeset-check:
|
|
10
|
+
name: Check for changeset
|
|
11
|
+
# Skip the check on the automated Release PR.
|
|
12
|
+
if: ${{ github.head_ref != 'changeset-release/main' }}
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
|
|
20
|
+
- name: Check for changeset files
|
|
21
|
+
uses: actions/github-script@v7
|
|
22
|
+
with:
|
|
23
|
+
script: |
|
|
24
|
+
const { data: files } = await github.rest.pulls.listFiles({
|
|
25
|
+
owner: context.repo.owner,
|
|
26
|
+
repo: context.repo.repo,
|
|
27
|
+
pull_number: context.issue.number,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const hasChangeset = files.some(f =>
|
|
31
|
+
f.filename.startsWith('.changeset/') &&
|
|
32
|
+
f.filename.endsWith('.md') &&
|
|
33
|
+
f.filename !== '.changeset/README.md'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (!hasChangeset) {
|
|
37
|
+
await github.rest.issues.createComment({
|
|
38
|
+
owner: context.repo.owner,
|
|
39
|
+
repo: context.repo.repo,
|
|
40
|
+
issue_number: context.issue.number,
|
|
41
|
+
body: "No changeset found. If this PR should trigger a release, run `npx changeset` and commit the generated file.\n\nIf this change doesn't need a release (docs, CI config, etc.), you can ignore this message."
|
|
42
|
+
});
|
|
43
|
+
core.warning('No changeset file found in this PR.');
|
|
44
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-test:
|
|
10
|
+
name: Build & Test
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Detect Release PR
|
|
14
|
+
id: rpr
|
|
15
|
+
run: |
|
|
16
|
+
if [[ "${{ github.event.pull_request.head.ref }}" == "changeset-release/main" ]]; then
|
|
17
|
+
echo "is_release_pr=true" >> $GITHUB_OUTPUT
|
|
18
|
+
echo "Release PR from changesets/action detected — skipping build/test (auto-generated version+CHANGELOG only)."
|
|
19
|
+
else
|
|
20
|
+
echo "is_release_pr=false" >> $GITHUB_OUTPUT
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
- name: Checkout
|
|
24
|
+
if: steps.rpr.outputs.is_release_pr == 'false'
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Setup Node.js
|
|
28
|
+
if: steps.rpr.outputs.is_release_pr == 'false'
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: 22.16.0
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
if: steps.rpr.outputs.is_release_pr == 'false'
|
|
35
|
+
run: npm ci --legacy-peer-deps
|
|
36
|
+
|
|
37
|
+
- name: Build
|
|
38
|
+
if: steps.rpr.outputs.is_release_pr == 'false'
|
|
39
|
+
run: npm run build
|
|
40
|
+
|
|
41
|
+
- name: Test
|
|
42
|
+
if: steps.rpr.outputs.is_release_pr == 'false'
|
|
43
|
+
run: npm test --if-present
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
release:
|
|
12
|
+
name: Publish Release
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: write
|
|
17
|
+
# `--provenance` signs the tarball with a GitHub OIDC token, so the job must be able to
|
|
18
|
+
# mint one. This does NOT switch the package to OIDC trusted publishing — authentication
|
|
19
|
+
# is still the org npm token.
|
|
20
|
+
id-token: write
|
|
21
|
+
steps:
|
|
22
|
+
# Author the changesets "Version Packages" PR as the org release App (not the default
|
|
23
|
+
# GITHUB_TOKEN) so its CI runs without a manual "Approve and run" gate. Requires the org
|
|
24
|
+
# App installed on this repo + org secrets RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY.
|
|
25
|
+
- name: Generate GitHub App token
|
|
26
|
+
id: app-token
|
|
27
|
+
uses: actions/create-github-app-token@v2
|
|
28
|
+
with:
|
|
29
|
+
app-id: ${{ secrets.RELEASE_APP_ID }}
|
|
30
|
+
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
|
31
|
+
|
|
32
|
+
- name: Checkout
|
|
33
|
+
uses: actions/checkout@v4
|
|
34
|
+
with:
|
|
35
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
36
|
+
|
|
37
|
+
- name: Setup Node.js
|
|
38
|
+
uses: actions/setup-node@v4
|
|
39
|
+
with:
|
|
40
|
+
node-version: 22.16.0
|
|
41
|
+
registry-url: 'https://registry.npmjs.org'
|
|
42
|
+
|
|
43
|
+
# `npm stage` landed in CLI 11.15.0; Node 22.16 ships npm 10.x, so the bundled one
|
|
44
|
+
# cannot stage. Pinned rather than `@latest` so a future npm release cannot change how
|
|
45
|
+
# releases behave without a commit here.
|
|
46
|
+
- name: Use an npm that can stage
|
|
47
|
+
run: npm i -g npm@^11.15.0
|
|
48
|
+
|
|
49
|
+
- name: Install dependencies
|
|
50
|
+
run: npm ci --legacy-peer-deps
|
|
51
|
+
|
|
52
|
+
- name: Build
|
|
53
|
+
run: npm run build
|
|
54
|
+
|
|
55
|
+
# No `publish:` — changesets only opens/updates the version PR here. Publishing is the
|
|
56
|
+
# step below, because `changeset publish` shells out to `npm publish`, which a
|
|
57
|
+
# stage-only token cannot do (changesets/changesets#2025 is open for first-class
|
|
58
|
+
# support). Splitting them keeps changesets doing what it is good at — versions and
|
|
59
|
+
# changelogs — and leaves the registry call to us.
|
|
60
|
+
- name: Create release Pull Request
|
|
61
|
+
id: changesets
|
|
62
|
+
uses: changesets/action@v1
|
|
63
|
+
with:
|
|
64
|
+
title: 'chore: release'
|
|
65
|
+
commit: 'chore: release'
|
|
66
|
+
env:
|
|
67
|
+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
68
|
+
|
|
69
|
+
# Stage the version for a human to approve.
|
|
70
|
+
#
|
|
71
|
+
# A staged version is uploaded but NOT public: a maintainer reviews it and approves with
|
|
72
|
+
# 2FA, from the Staged Packages tab in the npm user menu or `npm stage approve`. That is
|
|
73
|
+
# the point — every release keeps a proof-of-presence step even though CI is
|
|
74
|
+
# unattended — and it is why the org token is scoped "read and write (stage only)".
|
|
75
|
+
#
|
|
76
|
+
# Idempotent: this workflow runs on every push to main, including the merge of the
|
|
77
|
+
# version PR and any later commit, so it must do nothing when the version is already on
|
|
78
|
+
# the registry or already sitting in the queue.
|
|
79
|
+
- name: Stage the release for approval
|
|
80
|
+
if: steps.changesets.outputs.hasChangesets != 'true'
|
|
81
|
+
env:
|
|
82
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
|
83
|
+
NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
|
84
|
+
run: |
|
|
85
|
+
set -euo pipefail
|
|
86
|
+
name=$(node -p "require('./package.json').name")
|
|
87
|
+
version=$(node -p "require('./package.json').version")
|
|
88
|
+
private=$(node -p "require('./package.json').private === true")
|
|
89
|
+
if [ "$private" = "true" ]; then
|
|
90
|
+
echo "$name is private — nothing to publish."; exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if npm view "$name@$version" version >/dev/null 2>&1; then
|
|
94
|
+
echo "$name@$version is already on the registry — nothing to do."
|
|
95
|
+
exit 0
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
if npm stage list "$name" 2>/dev/null | grep -q "$version"; then
|
|
99
|
+
echo "$name@$version is already staged and waiting for approval."
|
|
100
|
+
exit 0
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
echo "Staging $name@$version…"
|
|
104
|
+
# Capture the output: `npm stage publish` prints the stage id, and `npm stage
|
|
105
|
+
# approve` takes ONLY that id — a package spec is rejected with "stage-id must be a
|
|
106
|
+
# valid UUID". Without this the notice below hands out a command that does not work.
|
|
107
|
+
out=$(npm stage publish --access public --provenance 2>&1 | tee /dev/stderr)
|
|
108
|
+
uuid='[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
|
|
109
|
+
# `|| true` because the script runs under `set -euo pipefail`: a grep that matches
|
|
110
|
+
# nothing exits 1 and would fail the step even though the staging itself succeeded.
|
|
111
|
+
stage_id=$(printf '%s' "$out" | grep -oE "$uuid" | tail -1 || true)
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
echo "### 📦 \`$name@$version\` is staged, not published"
|
|
115
|
+
echo
|
|
116
|
+
echo "It is uploaded and held for review. **Approve it to make it public:**"
|
|
117
|
+
echo
|
|
118
|
+
if [ -n "$stage_id" ]; then
|
|
119
|
+
echo "- **CLI:** \`npm stage approve $stage_id\`"
|
|
120
|
+
else
|
|
121
|
+
echo "- **CLI:** \`npm stage list $name\` to find the id, then"
|
|
122
|
+
echo " \`npm stage approve <stage-id>\`"
|
|
123
|
+
fi
|
|
124
|
+
echo "- **Web:** [npmjs.com](https://www.npmjs.com) → your avatar → **Staged"
|
|
125
|
+
echo " Packages** → **Approve**. The button stays disabled until npm has"
|
|
126
|
+
echo " finished scanning the tarball; the page refreshes every minute."
|
|
127
|
+
echo
|
|
128
|
+
echo "Both prompt for 2FA. Until then \`npm install $name\` still resolves"
|
|
129
|
+
echo "\`$(npm view "$name" version 2>/dev/null || echo 'nothing')\`."
|
|
130
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
131
|
+
|
|
132
|
+
if [ -n "$stage_id" ]; then
|
|
133
|
+
echo "::notice title=Approval needed::$name@$version is staged. Run: npm stage approve $stage_id"
|
|
134
|
+
else
|
|
135
|
+
echo "::notice title=Approval needed::$name@$version is staged, but the stage id could not be read from the output. Run: npm stage list $name"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# When changesets opened/updated the version PR, merge it so the release reaches the
|
|
139
|
+
# staging queue without a manual click. App token → the merge's push re-triggers this
|
|
140
|
+
# workflow, which then stages. DIRECT-merge (not `--auto`): GitHub
|
|
141
|
+
# auto-merge ignores branch-protection review-bypass allowances; main is check-only so a
|
|
142
|
+
# direct merge lands once the required check is green — retry until then.
|
|
143
|
+
- name: Merge the version PR to stage the release
|
|
144
|
+
if: steps.changesets.outputs.hasChangesets == 'true'
|
|
145
|
+
env:
|
|
146
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
147
|
+
run: |
|
|
148
|
+
pr=$(gh pr list --base main --head changeset-release/main --state open --json number --jq '.[0].number // empty')
|
|
149
|
+
if [ -z "$pr" ]; then echo "No open version PR (nothing to merge)."; exit 0; fi
|
|
150
|
+
for i in $(seq 1 40); do
|
|
151
|
+
if gh pr merge "$pr" --merge 2>/tmp/merge_err; then
|
|
152
|
+
echo "Merged version PR #$pr on attempt $i."
|
|
153
|
+
exit 0
|
|
154
|
+
fi
|
|
155
|
+
echo "Attempt $i/40: version PR #$pr not mergeable yet ($(tr -d '\n' < /tmp/merge_err)); waiting for the required check…"
|
|
156
|
+
sleep 15
|
|
157
|
+
done
|
|
158
|
+
echo "::warning::Version PR #$pr not merged after retries — merge it manually."
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @\_linked/ui
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#7](https://github.com/linked-cm/ui/pull/7) [`be0c4ef`](https://github.com/linked-cm/ui/commit/be0c4ef095d30cd1388517f7d13383eb26b4926c) Thanks [@flyon](https://github.com/flyon)! - Rename from `@_linked/ui` to `@_linked/shape-ui`.
|
|
8
|
+
|
|
9
|
+
`ui` said only "not backend", which is the least informative name available for the layer
|
|
10
|
+
most in need of one that states its contract. Every component here takes a shape and a
|
|
11
|
+
property shape and renders a control for it, working on any shape rather than a known one.
|
|
12
|
+
`shape-ui` says that.
|
|
13
|
+
|
|
14
|
+
Renaming now because it is nearly free: the package has three consumers. It becomes
|
|
15
|
+
expensive as soon as it has more, and this layer should have more.
|
|
16
|
+
|
|
17
|
+
Also removes nine compiled CommonJS files that had been committed into `src/` alongside their
|
|
18
|
+
`.tsx` sources, and a dead `ShapeTable.tsx.old`.
|
|
19
|
+
|
|
20
|
+
## 1.0.3
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- [#3](https://github.com/linked-cm/ui/pull/3) [`24d8c4b`](https://github.com/linked-cm/ui/commit/24d8c4bdd0e97d01dacdda8dcc94b17cfad84ca8) Thanks [@flyon](https://github.com/flyon)! - loadData: ESM-only JSON import — drop the dead CJS branch, add the `{ with: { type: 'json' } }` import attribute.
|
|
25
|
+
|
|
26
|
+
## 1.0.2
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- [`56ee32e`](https://github.com/linked-cm/ui/commit/56ee32ef1e709b8b6841870c53a73e285c68b6c7) - Initial release under the new publishing setup.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# `@_linked/shape-ui`
|
|
2
|
+
|
|
3
|
+
UI driven by a shape.
|
|
4
|
+
|
|
5
|
+
Each component takes a `Shape` and a property shape and renders a control for it — a text
|
|
6
|
+
field, a select, a date picker, an avatar. It works on *any* shape, not a known one, which is
|
|
7
|
+
the whole point: an application that adds a property gets an editor for it without writing
|
|
8
|
+
one.
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
<TextfieldEditor of={person} property={givenName} />
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Where it sits
|
|
15
|
+
|
|
16
|
+
| Layer | Package | Knows about |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Design tokens | `@_linked/css` | nothing |
|
|
19
|
+
| Headless components | `@_linked/primitives` | the DOM and the tokens |
|
|
20
|
+
| Data binding | `@_linked/react` | shapes and queries; ships no components |
|
|
21
|
+
| **Shape-driven UI** | **`@_linked/shape-ui`** | how to render an arbitrary shape |
|
|
22
|
+
| Product surfaces | applications | one product's domain vocabulary |
|
|
23
|
+
|
|
24
|
+
Everything here renders a `@_linked/primitives` control and adds the shape binding. Nothing
|
|
25
|
+
here knows about a specific product.
|
|
26
|
+
|
|
27
|
+
**Consume this layer rather than rebuilding it.** A product that needs a shape-driven form
|
|
28
|
+
field extends what is here; growing a second implementation inside an application is how the
|
|
29
|
+
same component ends up existing three times, and then drifting.
|
|
30
|
+
|
|
31
|
+
## Why the name changed
|
|
32
|
+
|
|
33
|
+
This package was `@_linked/ui`. That name said only "not backend" — the least informative
|
|
34
|
+
label available for the layer most in need of one that states its contract. `shape-ui` says
|
|
35
|
+
what it is.
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/backend.ts"],"names":[],"mappings":"AAAA,gEAAgE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Shape } from '@_linked/core/shapes/Shape';
|
|
3
|
+
import { PropertyShape } from '@_linked/core/shapes/SHACL';
|
|
4
|
+
export interface AvatarEditorProps {
|
|
5
|
+
of?: Shape;
|
|
6
|
+
property?: PropertyShape;
|
|
7
|
+
/**
|
|
8
|
+
* Converts the value returned by the shape, to the input string for the avatar
|
|
9
|
+
* @param shapePropertyValue
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
preConvertValueFn?: (shapePropertyValue: any) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Converts the value of the avatar to a value that can be provided to the set method of the shape
|
|
15
|
+
* @param inputValue
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
postConvertValueFn?: (inputValue: string) => any;
|
|
19
|
+
}
|
|
20
|
+
export declare const AvatarEditor: ({ of, property, preConvertValueFn, postConvertValueFn, ...restProps }: AvatarEditorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Root, Image } from '@_linked/primitives/components/Avatar';
|
|
3
|
+
export const AvatarEditor = ({ of, property, preConvertValueFn, postConvertValueFn, ...restProps }) => {
|
|
4
|
+
return (React.createElement(Root, null,
|
|
5
|
+
React.createElement(Image, null)));
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=AvatarEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AvatarEditor.js","sourceRoot":"","sources":["../../../src/components/AvatarEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,uCAAuC,CAAC;AAoBpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,EAAE,EACF,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,GAAG,SAAS,EACM,EAAE,EAAE;IACtB,OAAO,CACL,oBAAC,IAAI;QACH,oBAAC,KAAK,OAAG,CACJ,CACR,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Shape } from '@_linked/core/shapes/Shape';
|
|
3
|
+
import { PropertyShape } from '@_linked/core/shapes/SHACL';
|
|
4
|
+
export interface CheckboxEditorProps {
|
|
5
|
+
onCheckedChange?: (e: any) => void;
|
|
6
|
+
of?: Shape;
|
|
7
|
+
property?: PropertyShape;
|
|
8
|
+
/**
|
|
9
|
+
* Converts the value returned by the shape, to the input string for the checkbox
|
|
10
|
+
* @param shapePropertyValue
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
preConvertValueFn?: (shapePropertyValue: any) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Converts the value of the checkbox to a value that can be provided to the set method of the shape
|
|
16
|
+
* @param inputValue
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
postConvertValueFn?: (inputValue: string) => any;
|
|
20
|
+
}
|
|
21
|
+
export declare const CheckboxEditor: ({ onCheckedChange, of, property, preConvertValueFn, postConvertValueFn, ...restProps }: CheckboxEditorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Checkbox } from '@_linked/primitives/components/Checkbox';
|
|
3
|
+
import style from './CheckboxEditor.module.css';
|
|
4
|
+
export const CheckboxEditor = ({ onCheckedChange, of, property, preConvertValueFn, postConvertValueFn, ...restProps }) => {
|
|
5
|
+
const currentValues = of[property.label];
|
|
6
|
+
const onChangeHandler = (item, checked) => {
|
|
7
|
+
if (!of)
|
|
8
|
+
return;
|
|
9
|
+
if (property.in) {
|
|
10
|
+
if (checked) {
|
|
11
|
+
currentValues.add(item);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
currentValues.delete(item);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
of[property.label] = checked;
|
|
19
|
+
}
|
|
20
|
+
if (onCheckedChange) {
|
|
21
|
+
onCheckedChange(currentValues);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return (React.createElement(React.Fragment, null, property.in ? (property.in.map((item, i) => {
|
|
25
|
+
return (React.createElement("label", { className: style.Root },
|
|
26
|
+
React.createElement(Checkbox, { value: of[property.label], onCheckedChange: onChangeHandler.bind(this, item), defaultChecked: currentValues.has(item), ...restProps }),
|
|
27
|
+
"TODO: ",
|
|
28
|
+
item.toString()));
|
|
29
|
+
})) : (React.createElement("div", null, "checkbox usage unimplemented")
|
|
30
|
+
// <Checkbox
|
|
31
|
+
// value={of[property.label]}
|
|
32
|
+
// onCheckedChange={onChangeHandler}
|
|
33
|
+
// defaultChecked={
|
|
34
|
+
// of
|
|
35
|
+
// ? preConvertValueFn
|
|
36
|
+
// ? preConvertValueFn(of[property.label])
|
|
37
|
+
// : of[property.label]
|
|
38
|
+
// : ''
|
|
39
|
+
// }
|
|
40
|
+
// {...restProps}
|
|
41
|
+
// />
|
|
42
|
+
)));
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=CheckboxEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxEditor.js","sourceRoot":"","sources":["../../../src/components/CheckboxEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AAEnE,OAAO,KAAK,MAAM,6BAA6B,CAAC;AAqBhD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAC7B,eAAe,EACf,EAAE,EACF,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,GAAG,SAAS,EACQ,EAAE,EAAE;IACxB,MAAM,aAAa,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QACxC,IAAI,CAAC,EAAE;YAAE,OAAO;QAEhB,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,IAAI,OAAO,EAAE,CAAC;gBACZ,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QAC/B,CAAC;QAED,IAAI,eAAe,EAAE,CAAC;YACpB,eAAe,CAAC,aAAa,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,0CACG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CACb,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC1B,OAAO,CACL,+BAAO,SAAS,EAAE,KAAK,CAAC,IAAI;YAC1B,oBAAC,QAAQ,IACP,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EACzB,eAAe,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EACjD,cAAc,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KACnC,SAAS,GACb;;YACK,IAAI,CAAC,QAAQ,EAAE,CAChB,CACT,CAAC;IACJ,CAAC,CAAC,CACH,CAAC,CAAC,CAAC,CACF,gEAAuC;IACvC,YAAY;IACZ,+BAA+B;IAC/B,sCAAsC;IACtC,qBAAqB;IACrB,SAAS;IACT,4BAA4B;IAC5B,kDAAkD;IAClD,+BAA+B;IAC/B,aAAa;IACb,MAAM;IACN,mBAAmB;IACnB,KAAK;KACN,CACA,CACJ,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Shape } from '@_linked/core/shapes/Shape';
|
|
3
|
+
export interface DateEditorProps {
|
|
4
|
+
onChange?: (e: any) => void;
|
|
5
|
+
of?: Shape;
|
|
6
|
+
property?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Converts the value returned by the shape, to the date string for the date field
|
|
9
|
+
* @param shapePropertyValue
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
preConvertValueFn?: (shapePropertyValue: any) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Converts the value of the date field to a value that can be provided to the set method of the shape
|
|
15
|
+
* @param inputValue
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
postConvertValueFn?: (inputValue: string) => any;
|
|
19
|
+
}
|
|
20
|
+
export declare const DateEditor: ({ onChange, of, property, preConvertValueFn, postConvertValueFn, ...restProps }: DateEditorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export const DateEditor = ({ onChange, of, property, preConvertValueFn, postConvertValueFn, ...restProps }) => {
|
|
3
|
+
const onChangeHandler = (e) => {
|
|
4
|
+
if (onChange) {
|
|
5
|
+
onChange(e);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
return (React.createElement(React.Fragment, null)
|
|
9
|
+
// <Input
|
|
10
|
+
// onChange={onChangeHandler}
|
|
11
|
+
// defaultValue={
|
|
12
|
+
// of
|
|
13
|
+
// ? preConvertValueFn
|
|
14
|
+
// ? preConvertValueFn(of[property])
|
|
15
|
+
// : of[property]
|
|
16
|
+
// : ''
|
|
17
|
+
// }
|
|
18
|
+
// {...restProps}
|
|
19
|
+
// />
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=DateEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateEditor.js","sourceRoot":"","sources":["../../../src/components/DateEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAqBxC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,QAAQ,EACR,EAAE,EACF,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAElB,GAAG,SAAS,EACI,EAAE,EAAE;IACpB,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,EAAE;QAC5B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,yCAAK;IACL,SAAS;IACT,+BAA+B;IAC/B,mBAAmB;IACnB,SAAS;IACT,4BAA4B;IAC5B,4CAA4C;IAC5C,yBAAyB;IACzB,aAAa;IACb,MAAM;IACN,mBAAmB;IACnB,KAAK;KACN,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Shape } from '@_linked/core/shapes/Shape';
|
|
3
|
+
import { PropertyShape } from '@_linked/core/shapes/SHACL';
|
|
4
|
+
export interface RadioButtonProps {
|
|
5
|
+
onValueChange?: (newValue: any) => void;
|
|
6
|
+
of?: Shape;
|
|
7
|
+
property?: PropertyShape;
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Converts the value returned by the shape, to the radio input string for the radio input
|
|
12
|
+
* @param shapePropertyValue
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
preConvertValueFn?: (shapePropertyValue: any) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Converts the value of the radio input to a value that can be provided to the set method of the shape
|
|
18
|
+
* @param radioInputValue
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
postConvertValueFn?: (radioInputValue: string) => any;
|
|
22
|
+
}
|
|
23
|
+
export declare const RadioButtonEditor: React.FC<RadioButtonProps>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { RadioGroup } from '@_linked/primitives/components/RadioGroup';
|
|
3
|
+
import styles from './RadioButtonEditor.module.css';
|
|
4
|
+
import { cl } from '@_linked/react/utils/ClassNames';
|
|
5
|
+
export const RadioButtonEditor = ({ onValueChange, of, property, preConvertValueFn, postConvertValueFn, children, className, ...props }) => {
|
|
6
|
+
const [labelHasLongString, setLabelHasLongString] = useState(false);
|
|
7
|
+
const onChangeHandler = (newValue) => {
|
|
8
|
+
if (!of)
|
|
9
|
+
return;
|
|
10
|
+
of[property.label] = newValue;
|
|
11
|
+
if (onValueChange) {
|
|
12
|
+
onValueChange(of[property.label]);
|
|
13
|
+
// onValueChange(
|
|
14
|
+
// options.map((option) => {
|
|
15
|
+
// console.log(option, 'option');
|
|
16
|
+
// of[property.label] = newValue;
|
|
17
|
+
// }),
|
|
18
|
+
// );
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
//check if radio button label has a long string
|
|
23
|
+
if (property.in) {
|
|
24
|
+
const containsLongString = property.in.some((list) => {
|
|
25
|
+
throw Error('TODO: property.in for RadioButtonEditor');
|
|
26
|
+
// const wordCount = list.value.split(' ').length;
|
|
27
|
+
// return wordCount > 5;
|
|
28
|
+
});
|
|
29
|
+
setLabelHasLongString(containsLongString);
|
|
30
|
+
}
|
|
31
|
+
}, [property.in]);
|
|
32
|
+
// function cl(radioButtonField: any, arg1: any): string {
|
|
33
|
+
// throw new Error('Function not implemented.');
|
|
34
|
+
// }
|
|
35
|
+
console.log('of.label', of[property.label]);
|
|
36
|
+
return (React.createElement(React.Fragment, null,
|
|
37
|
+
React.createElement(RadioGroup.Root, { defaultValue: "default", "aria-label": "View density", className: cl(styles.Root, labelHasLongString && styles.columnBased) }, property.in ? (property.in.map((item) => (React.createElement("label", { className: styles.radioButtonItem },
|
|
38
|
+
React.createElement(RadioGroup.Item, { value: item.toString(), className: styles.radioButton }),
|
|
39
|
+
"TODO: item from property.in")))) : (React.createElement("p", null, "unimplemented single radio button")))));
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=RadioButtonEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioButtonEditor.js","sourceRoot":"","sources":["../../../src/components/RadioButtonEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAc,UAAU,EAAE,MAAM,2CAA2C,CAAC;AAEnF,OAAO,MAAM,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,iCAAiC,CAAC;AAsBrD,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,EAC5D,aAAa,EACb,EAAE,EACF,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpE,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,EAAE;QACnC,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;QAE9B,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YAClC,iBAAiB;YACjB,8BAA8B;YAC9B,qCAAqC;YACrC,qCAAqC;YACrC,QAAQ;YACR,KAAK;QACP,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,+CAA+C;QAC/C,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,kBAAkB,GAAG,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBACnD,MAAM,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBACvD,kDAAkD;gBAClD,wBAAwB;YAC1B,CAAC,CAAC,CAAC;YACH,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAElB,0DAA0D;IAC1D,kDAAkD;IAClD,IAAI;IAEJ,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAE5C,OAAO,CACL;QACE,oBAAC,UAAU,CAAC,IAAI,IACd,YAAY,EAAC,SAAS,gBACX,cAAc,EACzB,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,IAAI,MAAM,CAAC,WAAW,CAAC,IAEnE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CACb,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACxB,+BAAO,SAAS,EAAE,MAAM,CAAC,eAAe;YACtC,oBAAC,UAAU,CAAC,IAAI,IACd,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,EACtB,SAAS,EAAE,MAAM,CAAC,WAAW,GAC7B;0CAGI,CACT,CAAC,CACH,CAAC,CAAC,CAAC,CACF,mEAAwC,CACzC,CACe,CACjB,CACJ,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.Root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: row;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
gap: 1rem;
|
|
6
|
+
|
|
7
|
+
&.columnBased {
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
padding: 10px 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.radioButtonItem {
|
|
13
|
+
display: flex;
|
|
14
|
+
gap: 0.5rem;
|
|
15
|
+
align-items: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.radioButton {
|
|
19
|
+
width: 25px;
|
|
20
|
+
min-width: 25px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Shape } from '@_linked/core/shapes/Shape';
|
|
3
|
+
import { PropertyShape } from '@_linked/core/shapes/SHACL';
|
|
4
|
+
export interface SelectEditorProps {
|
|
5
|
+
onValueChange?: (e: any) => void;
|
|
6
|
+
of?: Shape;
|
|
7
|
+
property?: PropertyShape;
|
|
8
|
+
/**
|
|
9
|
+
* Converts the value returned by the shape, to the input string for the select
|
|
10
|
+
* @param shapePropertyValue
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
preConvertValueFn?: (shapePropertyValue: any) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Converts the value of the select to a value that can be provided to the set method of the shape
|
|
16
|
+
* @param inputValue
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
postConvertValueFn?: (inputValue: string) => any;
|
|
20
|
+
}
|
|
21
|
+
export declare const SelectEditor: ({ onValueChange, of, property, preConvertValueFn, postConvertValueFn, ...restProps }: SelectEditorProps) => React.JSX.Element;
|