tosijs-ui 1.15.4 → 1.16.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/NOTICE +28 -0
  3. package/bin/caddy-install.ts +4 -4
  4. package/bin/format.ts +96 -0
  5. package/bin/release-notes.ts +24 -4
  6. package/dist/ab-test.d.ts +6 -6
  7. package/dist/ab-test.js +5 -6
  8. package/dist/babylon-3d.d.ts +8 -8
  9. package/dist/babylon-3d.js +15 -16
  10. package/dist/bodymovin-player.d.ts +7 -6
  11. package/dist/bodymovin-player.js +5 -6
  12. package/dist/carousel.d.ts +12 -11
  13. package/dist/carousel.js +10 -11
  14. package/dist/code-editor.d.ts +6 -6
  15. package/dist/code-editor.js +5 -6
  16. package/dist/crud.d.ts +9 -9
  17. package/dist/crud.js +8 -9
  18. package/dist/data-table.d.ts +19 -18
  19. package/dist/data-table.js +17 -18
  20. package/dist/diff.d.ts +9 -9
  21. package/dist/diff.js +15 -16
  22. package/dist/doc-system/css-var-editor.d.ts +6 -6
  23. package/dist/doc-system/css-var-editor.js +5 -6
  24. package/dist/doc-system/doc-system.d.ts +13 -12
  25. package/dist/doc-system/doc-system.js +19 -20
  26. package/dist/doc-system/release-notes.d.ts +15 -0
  27. package/dist/doc-system/release-notes.js +30 -0
  28. package/dist/doc-system/site/generate-site.d.ts +7 -7
  29. package/dist/doc-system/site/generate-site.js +3 -1
  30. package/dist/doc-system/site/host-preset.d.ts +2 -2
  31. package/dist/doc-system/site/host-preset.js +2 -2
  32. package/dist/doc-system/site/orchestrator.js +17 -5
  33. package/dist/editable-rect.d.ts +6 -7
  34. package/dist/editable-rect.js +5 -6
  35. package/dist/filter-builder.d.ts +6 -6
  36. package/dist/filter-builder.js +6 -7
  37. package/dist/float.d.ts +8 -7
  38. package/dist/float.js +6 -7
  39. package/dist/form.d.ts +17 -16
  40. package/dist/form.js +15 -16
  41. package/dist/highlight-block.d.ts +6 -6
  42. package/dist/highlight-block.js +5 -6
  43. package/dist/icons.d.ts +9 -9
  44. package/dist/icons.js +8 -9
  45. package/dist/iife.js +98 -98
  46. package/dist/iife.js.map +48 -48
  47. package/dist/index-iife.js +1 -1
  48. package/dist/layout.d.ts +22 -21
  49. package/dist/layout.js +18 -21
  50. package/dist/live-example/component.d.ts +8 -7
  51. package/dist/live-example/component.js +10 -11
  52. package/dist/live-example/error-location.js +2 -1
  53. package/dist/localize.d.ts +8 -9
  54. package/dist/localize.js +7 -9
  55. package/dist/mapbox.d.ts +9 -8
  56. package/dist/mapbox.js +7 -8
  57. package/dist/markdown-viewer.d.ts +9 -12
  58. package/dist/markdown-viewer.js +62 -42
  59. package/dist/menu.d.ts +11 -11
  60. package/dist/menu.js +19 -18
  61. package/dist/month.d.ts +16 -16
  62. package/dist/month.js +19 -20
  63. package/dist/password-strength.d.ts +7 -7
  64. package/dist/password-strength.js +6 -7
  65. package/dist/pocket-bar.d.ts +7 -7
  66. package/dist/pocket-bar.js +6 -7
  67. package/dist/rating.d.ts +18 -17
  68. package/dist/rating.js +16 -17
  69. package/dist/rich-text.d.ts +7 -7
  70. package/dist/rich-text.js +6 -7
  71. package/dist/router.d.ts +6 -5
  72. package/dist/router.js +4 -5
  73. package/dist/schema-form.d.ts +5 -5
  74. package/dist/schema-form.js +4 -5
  75. package/dist/segmented.d.ts +12 -12
  76. package/dist/segmented.js +10 -11
  77. package/dist/select.d.ts +16 -13
  78. package/dist/select.js +49 -20
  79. package/dist/side-nav.d.ts +9 -9
  80. package/dist/side-nav.js +16 -17
  81. package/dist/size-break.d.ts +7 -6
  82. package/dist/size-break.js +5 -6
  83. package/dist/tab-selector.d.ts +6 -6
  84. package/dist/tab-selector.js +4 -5
  85. package/dist/tag-list.d.ts +15 -15
  86. package/dist/tag-list.js +13 -15
  87. package/dist/test-setup.d.ts +1 -0
  88. package/dist/test-setup.js +91 -0
  89. package/dist/version.d.ts +1 -1
  90. package/dist/version.js +1 -1
  91. package/llms.txt +2 -2
  92. package/package.json +16 -9
package/CHANGELOG.md CHANGED
@@ -1,5 +1,124 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.16.0
4
+
5
+ ### `<tosi-md>` sanitizes by default (#179)
6
+
7
+ **Breaking, as announced by 1.15.3's console warning.** A `<tosi-md>` with no `sanitize`
8
+ attribute now strips executable content, where it used to render raw HTML from the markdown.
9
+ Markdown from anyone other than you (issue bodies, comments, API data) could otherwise run
10
+ script in your page: tosijs-virta's review read a login token out of `localStorage` that way.
11
+
12
+ If your markdown deliberately embeds HTML that sanitizing removes (`script`, `style`, `iframe`,
13
+ `form`, event-handler attributes, `javascript:` or `data:` links, and a few more), set
14
+ `sanitize="off"` on that element, and only for markdown you control. Ordinary markdown, links
15
+ and inputs render exactly as before; custom elements do not (see the next paragraph). Only the exact value `off`
16
+ opts out; anything else, a typo included, sanitizes. The once-per-page warning is gone.
17
+
18
+ **Custom elements are unwrapped when sanitizing** (their sanitized content is kept, the element
19
+ is not): a component is code, and some render raw HTML or run code of their own, so untrusted
20
+ markdown must not be able to instantiate them. The pre-release review showed a nested
21
+ `<tosi-md sanitize="off">` escaping the sanitizer. Allow trusted display components by name
22
+ with the new `allowed-elements` attribute (space- or comma-separated), e.g.
23
+ `<tosi-md allowed-elements="tosi-icon tosi-tag">`, or the `allowedElements` property; changing it
24
+ re-renders. `tosi-md`, `tosi-example` and `tosi-doc-system` are never allowed, because they render
25
+ raw HTML or run code.
26
+
27
+ ### ESM doc sites no longer load their entry bundle twice (#191)
28
+
29
+ A doc site built with `bundleEntry` loaded its entry as `hydrate.js?v=<hash>`, while its
30
+ code-split chunks import the entry back as `../hydrate.js`. Those are different URLs, so the
31
+ browser created **two module instances of the entry** on every page: everything in it ran twice,
32
+ and a module that patches a prototype in a shared chunk threw on the second pass (Babylon's
33
+ `Cannot redefine property: onBeforeViewRenderObservable`, which also broke its shaders). Reported
34
+ with a clean before/after measurement by tosijs-3d-ensemble.
35
+
36
+ The entry is now built as **`hydrate-<hash>.js`** and loaded with no query string, so the page
37
+ and every chunk name one URL, and a rebuild still busts caches. **Rebuild your site to pick it
38
+ up.** Anything that refers to `hydrate.js` by name must follow the rename: CSP or SRI entries,
39
+ `<link rel="modulepreload">`, host cache rules, service workers, smoke checks.
40
+
41
+ ### Prettier never touches markdown, and `tosijs-format` (#187)
42
+
43
+ Markdown is authored prose, and in this stack the product: all Prettier did to it was escape
44
+ literal characters, pad tables and rewrite bullets and emphasis (`*n*` → `_n_`). tosijs-ui has
45
+ ignored it since 1.14.0, but the rule never reached the other repos. **The fix belongs in your
46
+ Prettier config**, where every entry point reads it (editors' format-on-save, lint-staged, a bare
47
+ `prettier --write`):
48
+
49
+ ```json
50
+ "overrides": [
51
+ { "files": ["*.md", "*.markdown", "*.mdx"], "options": { "requirePragma": true } }
52
+ ]
53
+ ```
54
+
55
+ **New `tosijs-format` bin**, a convenience on top: `eslint --fix` (when the project has an
56
+ `eslint.config.*`; its `ignores` decide the scope) then `prettier --write .`, excluding markdown on
57
+ the command line too. `tosijs-format --check` checks instead and exits 1 on anything unformatted or
58
+ any lint error, for CI. It uses your project's own Prettier and ESLint.
59
+
60
+ tosijs-ui's own CI now lints through it, which found 32 unused `Component` / `WebComponent`
61
+ imports left by this release's tosijs 1.10 migration (fixed before release; the migration had
62
+ passed every lane because nothing ran ESLint).
63
+
64
+ ### `tosijs-release-notes --check` reads only the section being released
65
+
66
+ It matched annotations against the whole CHANGELOG, so wording from OLDER releases could count a
67
+ new bullet as written up: this release's #191 fix had no entry and the gate still said "all
68
+ accounted for". It now reads only the section for the version being released and fails when that
69
+ section is missing. **Heading formats it recognises:** `## 1.16.0`, `## v1.16.0`, and Keep a
70
+ Changelog's `## [1.16.0]` / `## [v1.16.0]`, each with any suffix (a date, "(unreleased)"). The
71
+ section lookup is exported as `changelogSection`. If your gate goes red after upgrading, check
72
+ that the section heading names the exact version. When `package.json` still names the version that
73
+ is already tagged, it now says so ("bump the version before running --check") instead of
74
+ reporting every new bullet as unwritten.
75
+
76
+ ### tosijs 1.10: components are typed from their attributes
77
+
78
+ **Breaking, type-level only: the tosijs peer floor is now `^1.10.3`.** 1.10.0 removed
79
+ `Component`'s `[key: string]: any` index signature (tosijs#36), and 1.10.1 fixed the declaration
80
+ emit (TS2742, tosijs#38) that had blocked this adoption since 2026-09-04. Every component declares its
81
+ attributes with tosijs's `withAttributes()`, so a component instance is typed from its attribute
82
+ values: `tosiRating().max` is a `number`, a misspelt property is a type error, and so is
83
+ assigning the wrong type. On tosijs 1.9 TypeScript did not know `max` existed at all, because
84
+ `Component` carried an any-index signature that tosijs 1.10 removed (tosijs#36). Nothing changes
85
+ at runtime. Element-creator *arguments* are not typed by this. See
86
+ [Migrating](/migrating/) for your own components.
87
+
88
+ ### The CDN bundle updates tosijs-schema and grows 2.8kB
89
+
90
+ `dist/iife.js` (the single-`<script>` bundle) inlines tosijs-schema as the `<tosi-schema-form>`
91
+ validator; it moves from 1.8.0 to 1.10.2. It also carries tosijs 1.10 and the CodeMirror updates:
92
+ **+2.8kB gzip (+0.6%, 466,942 → 469,753 bytes)**. The ESM build is unaffected (tosijs-schema is an
93
+ optional peer there). `NOTICE` now attributes tosijs-schema and tosijs-kilpi, both bundled.
94
+
95
+ ## 1.15.5
96
+
97
+ ### `<tosi-select>` options can have keyboard shortcuts (#188)
98
+
99
+ `SelectOption` accepts `shortcut` (menu syntax, e.g. `'ctrl-1'`). It is shown in the popup, and
100
+ picks the option from the keyboard even while the popup is closed. A pick by shortcut sets
101
+ `value` and dispatches `change` exactly as a click does, so there is one code path. A disabled
102
+ select ignores its shortcuts.
103
+
104
+ ### Removed `<tosi-menu>`s no longer fire their shortcuts
105
+
106
+ `<tosi-menu>` added its document keydown listener with `capture: true` and removed it without,
107
+ which in a real browser removes nothing. Every menu ever taken off the page kept its listener,
108
+ and its keyboard shortcuts kept working. Only a real browser shows this (happy-dom removes the
109
+ listener anyway), so it is covered by a Playwright test in all three engines.
110
+
111
+ ### `tosijs-ui/test-setup`: the happy-dom preload, published (#170)
112
+
113
+ ```toml
114
+ [test]
115
+ preload = ["tosijs-ui/test-setup"]
116
+ ```
117
+
118
+ gives `bun test` a DOM that runs tosijs and tosijs-ui components. It needs `happy-dom` (an
119
+ optional peer). Use it instead of copying a `test-setup.ts` from another repo; the copies had
120
+ drifted three ways. It is also tosijs-ui's own preload, so every unit test here exercises it.
121
+
3
122
  ## 1.15.4
4
123
 
5
124
  ### `libraryBundle`: a library build Node can actually load (#169)
package/NOTICE CHANGED
@@ -71,6 +71,34 @@ Feather. The full permission notice is reproduced in `src/icons.ts` and on
71
71
  the icons documentation page.
72
72
  --------------------------------------------------------------------------
73
73
 
74
+ --------------------------------------------------------------------------
75
+ tosijs-kilpi — https://www.npmjs.com/package/tosijs-kilpi
76
+ Apache License 2.0. Bundled into `dist/iife.js` (the sanitizer behind
77
+ <tosi-md>). Reproduced from the tosijs-kilpi package's own NOTICE:
78
+
79
+ kilpi
80
+ Copyright 2026 Tonio Loewald
81
+
82
+ This product includes software developed as part of DOMPurify.
83
+
84
+ test/dompurify-fixtures.mjs is vendored verbatim from DOMPurify
85
+ (https://github.com/cure53/DOMPurify), test/fixtures/expect.mjs
86
+ Copyright (c) 2015 Mario Heiderich
87
+ Licensed under (MPL-2.0 OR Apache-2.0); used here under Apache-2.0.
88
+
89
+ That file is DOMPurify's published XSS payload corpus, used as kilpi's
90
+ verification gate. No DOMPurify source code is included or distributed in the
91
+ published package — the corpus is a test fixture only, and is not part of the
92
+ npm tarball.
93
+ --------------------------------------------------------------------------
94
+
95
+ --------------------------------------------------------------------------
96
+ tosijs-schema — https://github.com/tonioloewald/tosijs-schema
97
+ MIT. Bundled into `dist/iife.js`, which wires it in as the <tosi-schema-form>
98
+ validator for CDN users. The ESM build does not bundle it (it is an optional
99
+ peer there).
100
+ --------------------------------------------------------------------------
101
+
74
102
  --------------------------------------------------------------------------
75
103
  CodeMirror — https://codemirror.net/
76
104
  Copyright (c) by Marijn Haverbeke and others. MIT.
@@ -121,9 +121,9 @@ set -a; . /etc/caddy/preview.env; set +a
121
121
  : "\${ACME_EMAIL:?set ACME_EMAIL in /etc/caddy/preview.env}"
122
122
  : "\${PREVIEW_DOMAIN:?set PREVIEW_DOMAIN in /etc/caddy/preview.env}"
123
123
 
124
- sed -e "s|__PREVIEW_TOKEN__|\$PREVIEW_TOKEN|g" \\
125
- -e "s|{{ACME_EMAIL}}|\$ACME_EMAIL|g" \\
126
- -e "s|{{PREVIEW_DOMAIN}}|\$PREVIEW_DOMAIN|g" \\
124
+ sed -e "s|__PREVIEW_TOKEN__|$PREVIEW_TOKEN|g" \\
125
+ -e "s|{{ACME_EMAIL}}|$ACME_EMAIL|g" \\
126
+ -e "s|{{PREVIEW_DOMAIN}}|$PREVIEW_DOMAIN|g" \\
127
127
  /etc/caddy/Caddyfile.tpl > /etc/caddy/Caddyfile.new
128
128
 
129
129
  if grep -qE '\\{\\{|__PREVIEW_TOKEN__' /etc/caddy/Caddyfile.new; then
@@ -150,7 +150,7 @@ else
150
150
  echo "--- would change /etc/caddy/Caddyfile (token redacted) ---"
151
151
  if [ -f /etc/caddy/Caddyfile ]; then
152
152
  diff -u /etc/caddy/Caddyfile /etc/caddy/Caddyfile.new \\
153
- | sed "s|\$PREVIEW_TOKEN|***REDACTED***|g" || true
153
+ | sed "s|$PREVIEW_TOKEN|***REDACTED***|g" || true
154
154
  else
155
155
  echo "(no existing /etc/caddy/Caddyfile — this would create it)"
156
156
  fi
package/bin/format.ts ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env bun
2
+ /*
3
+ tosijs-format — the house format step, shipped as a command (#187).
4
+
5
+ tosijs-format eslint --fix, then prettier --write (markdown excluded)
6
+ tosijs-format --check eslint, then prettier --check (markdown excluded); exit 1 on any finding
7
+
8
+ **Prettier never touches markdown** in this stack. The rule itself lives in the Prettier
9
+ CONFIG, where every entry point reads it (editors, lint-staged, a bare `prettier --write`):
10
+
11
+ "overrides": [{ "files": ["*.md", "*.markdown", "*.mdx"], "options": { "requirePragma": true } }]
12
+
13
+ This command is a convenience on top: the house sequence in one step, excluding markdown on the
14
+ command line as well, so it holds even in a repo whose config hasn't got the override yet.
15
+ (1.16.0 first shipped this believing a v2 config could not exclude markdown; the pre-release
16
+ review showed `requirePragma` does, verified on 2.8.8 including editors' `--stdin-filepath`.)
17
+
18
+ Why markdown is excluded: markdown here is the PRODUCT (docs, a book, llms.txt). With
19
+ `proseWrap: preserve`, all Prettier did to it was escape literal characters, pad tables and
20
+ rewrite bullets and emphasis in authored prose.
21
+
22
+ ESLint runs only when the project has a flat config (`eslint.config.*`), over `.`, so the
23
+ project's own `ignores` decide the scope. Both tools come from the PROJECT's node_modules: this
24
+ is a formatting step, not a formatter, and the project pins the versions. Any step that fails
25
+ fails the command.
26
+ */
27
+
28
+ import { existsSync, readdirSync } from 'fs'
29
+ import { join } from 'path'
30
+ import { parseArgv } from './resolve-site-config.ts'
31
+
32
+ const { has } = parseArgv(process.argv.slice(2), {
33
+ bin: 'tosijs-format',
34
+ summary: 'the house format step: eslint, then prettier (never markdown)',
35
+ flags: ['check'],
36
+ usage:
37
+ ` tosijs-format eslint --fix ., then prettier --write . (markdown excluded)\n` +
38
+ ` tosijs-format --check check only: exit 1 on anything unformatted or any lint error\n\n` +
39
+ `Uses the project's own prettier and eslint (node_modules/.bin). ESLint runs only when the\n` +
40
+ `project has an eslint.config.* file.`,
41
+ })
42
+
43
+ const check = has('check')
44
+ const root = process.cwd()
45
+ const bin = (name: string) => join(root, 'node_modules', '.bin', name)
46
+
47
+ function run(argv: string[]): number {
48
+ const r = Bun.spawnSync(argv, {
49
+ cwd: root,
50
+ stdout: 'inherit',
51
+ stderr: 'inherit',
52
+ })
53
+ return r.exitCode ?? 1
54
+ }
55
+
56
+ if (!existsSync(bin('prettier'))) {
57
+ console.error(
58
+ '🛑 tosijs-format: prettier is not installed in this project (bun add -d prettier)'
59
+ )
60
+ process.exit(1)
61
+ }
62
+
63
+ let failed = false
64
+
65
+ /*
66
+ ESLint FIRST, then Prettier: `eslint --fix` rewrites code, and its output is not always what
67
+ Prettier would write, so running it second left files that `--check` then flagged (seen on the
68
+ first run of this command in tosijs-ui).
69
+ */
70
+ const hasEslintConfig = readdirSync(root).some((f) =>
71
+ /^eslint\.config\.[cm]?[jt]s$/.test(f)
72
+ )
73
+ if (hasEslintConfig) {
74
+ if (!existsSync(bin('eslint'))) {
75
+ console.error(
76
+ '🛑 tosijs-format: eslint.config found but eslint is not installed (bun add -d eslint)'
77
+ )
78
+ failed = true
79
+ } else if (run([bin('eslint'), '.', ...(check ? [] : ['--fix'])]) !== 0) {
80
+ failed = true
81
+ }
82
+ }
83
+
84
+ // The exclusion is the point of this command: prettier never touches markdown.
85
+ if (
86
+ run([
87
+ bin('prettier'),
88
+ check ? '--check' : '--write',
89
+ '.',
90
+ '!**/*.{md,markdown,mdx}',
91
+ ]) !== 0
92
+ ) {
93
+ failed = true
94
+ }
95
+
96
+ process.exit(failed ? 1 : 0)
@@ -67,6 +67,8 @@ import {
67
67
  collect,
68
68
  renderSection,
69
69
  uncovered,
70
+ changelogSection,
71
+ alreadyTagged,
70
72
  classifyBump,
71
73
  bumpConcerns,
72
74
  unsupportedClaims,
@@ -102,9 +104,25 @@ const total = records.flatMap((r) => r.bullets)
102
104
  const publishable = total.filter((b) => b.tag !== 'note')
103
105
 
104
106
  if (has('check')) {
105
- const changelog = await Bun.file('CHANGELOG.md')
107
+ const fullChangelog = await Bun.file('CHANGELOG.md')
106
108
  .text()
107
109
  .catch(() => '')
110
+ // Only the section being released counts: older prose must not cover a new bullet (B2).
111
+ const changelog = changelogSection(fullChangelog, version)
112
+ // An un-bumped version checks the section that was already RELEASED, and every new bullet
113
+ // then looks unwritten. Say that, instead of asking for prose that already exists.
114
+ if (alreadyTagged(since, version)) {
115
+ console.error(
116
+ `\n🛑 package.json is ${version}, which is already tagged ${since}. Bump the version ` +
117
+ `before running --check (or pass --version=X.Y.Z).`
118
+ )
119
+ process.exit(1)
120
+ }
121
+ if (!changelog && publishable.length) {
122
+ console.error(
123
+ `\n🛑 CHANGELOG.md has no \`## ${version}\` section to check against.`
124
+ )
125
+ }
108
126
  const missed = uncovered(records, changelog)
109
127
  const unsupported = unsupportedClaims(records)
110
128
  let bad = 0
@@ -114,7 +132,7 @@ if (has('check')) {
114
132
  console.error(
115
133
  `\n🛑 ${missed.length} annotation(s) since ${
116
134
  since || 'the start'
117
- } are not mentioned in CHANGELOG.md:\n`
135
+ } are not mentioned in the \`## ${version}\` section of CHANGELOG.md:\n`
118
136
  )
119
137
  for (const b of missed)
120
138
  console.error(` [${b.tag}] ${b.text} (${b.sha.slice(0, 8)})`)
@@ -146,7 +164,9 @@ if (has('check')) {
146
164
 
147
165
  So this keys on the diff and the annotations rather than on what the release was called.
148
166
  */
149
- const version = (await Bun.file('package.json').json()).version as string
167
+ // Named apart from the outer `version` (the --version flag): shadowing it put the CHANGELOG
168
+ // section lookup above in the temporal dead zone.
169
+ const pkgVersion = (await Bun.file('package.json').json()).version as string
150
170
  const changedPaths = since
151
171
  ? (await $`git diff --name-only ${since}...HEAD`.nothrow().quiet().text())
152
172
  .split('\n')
@@ -154,7 +174,7 @@ if (has('check')) {
154
174
  : []
155
175
  const concerns = since
156
176
  ? bumpConcerns({
157
- bump: classifyBump(since, version),
177
+ bump: classifyBump(since, pkgVersion),
158
178
  bullets: total,
159
179
  changedPaths,
160
180
  })
package/dist/ab-test.d.ts CHANGED
@@ -1,16 +1,16 @@
1
- import { Component } from 'tosijs';
2
- export declare class AbTest extends Component {
1
+ declare const AbTest_base: import("tosijs").WithAttributes<{
2
+ condition: string;
3
+ not: boolean;
4
+ }>;
5
+ export declare class AbTest extends AbTest_base {
3
6
  static preferredTagName: string;
4
7
  static set conditions(context: {
5
8
  [key: string]: any;
6
9
  });
7
- static initAttributes: {
8
- condition: string;
9
- not: boolean;
10
- };
11
10
  static instances: Set<AbTest>;
12
11
  connectedCallback(): void;
13
12
  disconnectedCallback(): void;
14
13
  render(): void;
15
14
  }
16
15
  export declare const abTest: import("tosijs").ElementCreator<AbTest>;
16
+ export {};
package/dist/ab-test.js CHANGED
@@ -76,9 +76,12 @@ randomize()
76
76
  - `not` reverses the condition (so `<tosi-ab not condition="foo">` will be visible if `conditions.foo` is `false`)
77
77
  */
78
78
  /*{ "parent": "Helper Libraries" }*/
79
- import { Component } from 'tosijs';
79
+ import { withAttributes } from 'tosijs';
80
80
  const abTestConditions = {};
81
- export class AbTest extends Component {
81
+ export class AbTest extends withAttributes({
82
+ condition: '',
83
+ not: false,
84
+ }) {
82
85
  static preferredTagName = 'tosi-ab';
83
86
  static set conditions(context) {
84
87
  Object.assign(abTestConditions, context);
@@ -86,10 +89,6 @@ export class AbTest extends Component {
86
89
  abTest.queueRender();
87
90
  }
88
91
  }
89
- static initAttributes = {
90
- condition: '',
91
- not: false,
92
- };
93
92
  static instances = new Set();
94
93
  connectedCallback() {
95
94
  super.connectedCallback();
@@ -1,4 +1,4 @@
1
- import { Component as WebComponent, ElementCreator } from 'tosijs';
1
+ import { ElementCreator } from 'tosijs';
2
2
  type B3dCallback = ((element: B3d, BABYLON: any) => void) | ((element: B3d, BABYLON: any) => Promise<void>);
3
3
  interface B3dUIOptions {
4
4
  snippetId?: string;
@@ -7,6 +7,12 @@ interface B3dUIOptions {
7
7
  size?: number;
8
8
  }
9
9
  type MeshProcessCallback = (meshes: any[]) => void;
10
+ declare const B3d_base: import("tosijs").WithAttributes<{
11
+ src: string;
12
+ clearColor: string;
13
+ fov: number;
14
+ heroLight: boolean;
15
+ }>;
10
16
  /**
11
17
  * @deprecated Use [`tosijs-3d`](https://www.npmjs.com/package/tosijs-3d) instead.
12
18
  *
@@ -17,14 +23,8 @@ type MeshProcessCallback = (meshes: any[]) => void;
17
23
  *
18
24
  * Still exported and still works. It will be removed in a future major.
19
25
  */
20
- export declare class B3d extends WebComponent {
26
+ export declare class B3d extends B3d_base {
21
27
  static preferredTagName: string;
22
- static initAttributes: {
23
- src: string;
24
- clearColor: string;
25
- fov: number;
26
- heroLight: boolean;
27
- };
28
28
  babylonReady: Promise<any>;
29
29
  BABYLON?: any;
30
30
  static shadowStyleSpec: {
@@ -221,7 +221,7 @@ be used to load `.glb` files. Setting `src` calls this for you on connect.
221
221
  `<tosi-3d>.loadUI(options: B3dUIOptions)` loads babylonjs guis, which you can create programmatically or using the [babylonjs gui tool](https://gui.babylonjs.com/).
222
222
  */
223
223
  /*{ "parent": "Components" }*/
224
- import { Component as WebComponent, elements } from 'tosijs';
224
+ import { elements, withAttributes } from 'tosijs';
225
225
  import { scriptTag } from './via-tag.js';
226
226
  import { icons, svg2DataUrl } from './icons.js';
227
227
  const noop = () => {
@@ -277,24 +277,23 @@ const warnDeprecated = () => {
277
277
  *
278
278
  * Still exported and still works. It will be removed in a future major.
279
279
  */
280
- export class B3d extends WebComponent {
280
+ export class B3d extends withAttributes({
281
+ // `src` (a .glb URL) makes <tosi-3d> work like <img>: the scene loads on connect.
282
+ src: '',
283
+ // scene background: a css hex color, or `transparent` to composite the 3D
284
+ // over the page (e.g. themed narrative pages). Empty = Babylon default.
285
+ clearColor: '',
286
+ // field-of-view MULTIPLIER on the camera's natural lens. 1 = unchanged,
287
+ // <1 = longer lens / less perspective distortion, >1 = wider. Author-friendly:
288
+ // no need to know Babylon's default fov in radians.
289
+ fov: 1,
290
+ // add a directional key light (front-upper-left) for a product-photography
291
+ // look, on top of the soft hemispheric fill.
292
+ heroLight: false,
293
+ }) {
281
294
  static preferredTagName = 'tosi-3d';
282
295
  // Declarative config so a scene can be assembled purely in HTML (no JS):
283
296
  // <tosi-3d src="/model.glb" hero-light fov="0.5" clear-color="transparent">
284
- static initAttributes = {
285
- // `src` (a .glb URL) makes <tosi-3d> work like <img>: the scene loads on connect.
286
- src: '',
287
- // scene background: a css hex color, or `transparent` to composite the 3D
288
- // over the page (e.g. themed narrative pages). Empty = Babylon default.
289
- clearColor: '',
290
- // field-of-view MULTIPLIER on the camera's natural lens. 1 = unchanged,
291
- // <1 = longer lens / less perspective distortion, >1 = wider. Author-friendly:
292
- // no need to know Babylon's default fov in radians.
293
- fov: 1,
294
- // add a directional key light (front-upper-left) for a product-photography
295
- // look, on top of the soft hemispheric fill.
296
- heroLight: false,
297
- };
298
297
  babylonReady;
299
298
  BABYLON;
300
299
  static shadowStyleSpec = {
@@ -1,4 +1,4 @@
1
- import { Component as WebComponent, ElementCreator } from 'tosijs';
1
+ import { ElementCreator } from 'tosijs';
2
2
  export interface LottieConfig {
3
3
  container?: HTMLElement | ShadowRoot;
4
4
  renderer: 'svg' | 'canvas' | 'html';
@@ -8,12 +8,12 @@ export interface LottieConfig {
8
8
  path?: string;
9
9
  [key: string]: any;
10
10
  }
11
- export declare class BodymovinPlayer extends WebComponent {
11
+ declare const BodymovinPlayer_base: import("tosijs").WithAttributes<{
12
+ src: string;
13
+ json: string;
14
+ }>;
15
+ export declare class BodymovinPlayer extends BodymovinPlayer_base {
12
16
  static preferredTagName: string;
13
- static initAttributes: {
14
- src: string;
15
- json: string;
16
- };
17
17
  content: null;
18
18
  config: LottieConfig;
19
19
  static bodymovinAvailable?: Promise<any>;
@@ -33,3 +33,4 @@ export declare class BodymovinPlayer extends WebComponent {
33
33
  render(): void;
34
34
  }
35
35
  export declare const bodymovinPlayer: ElementCreator<BodymovinPlayer>;
36
+ export {};
@@ -102,14 +102,13 @@ And of course just access the element's `animation` property to [use the bodymov
102
102
  Also see the [documentation for advanced interactions](https://lottiefiles.github.io/lottie-docs/advanced_interactions/)
103
103
  */
104
104
  /*{ "parent": "Components" }*/
105
- import { Component as WebComponent } from 'tosijs';
105
+ import { withAttributes } from 'tosijs';
106
106
  import { scriptTag } from './via-tag.js';
107
- export class BodymovinPlayer extends WebComponent {
107
+ export class BodymovinPlayer extends withAttributes({
108
+ src: '',
109
+ json: '',
110
+ }) {
108
111
  static preferredTagName = 'tosi-lottie';
109
- static initAttributes = {
110
- src: '',
111
- json: '',
112
- };
113
112
  content = null;
114
113
  config = {
115
114
  renderer: 'svg',
@@ -1,15 +1,15 @@
1
- import { Component as WebComponent, ElementCreator } from 'tosijs';
2
- export declare class TosiCarousel extends WebComponent {
1
+ import { ElementCreator } from 'tosijs';
2
+ declare const TosiCarousel_base: import("tosijs").WithAttributes<{
3
+ dots: boolean;
4
+ arrows: boolean;
5
+ maxVisibleItems: number;
6
+ snapDuration: number;
7
+ snapDelay: number;
8
+ loop: boolean;
9
+ auto: number;
10
+ }>;
11
+ export declare class TosiCarousel extends TosiCarousel_base {
3
12
  static preferredTagName: string;
4
- static initAttributes: {
5
- dots: boolean;
6
- arrows: boolean;
7
- maxVisibleItems: number;
8
- snapDuration: number;
9
- snapDelay: number;
10
- loop: boolean;
11
- auto: number;
12
- };
13
13
  private lastAutoAdvance;
14
14
  private interval?;
15
15
  private autoAdvance;
@@ -133,3 +133,4 @@ export declare const XinCarousel: typeof TosiCarousel;
133
133
  export declare const tosiCarousel: ElementCreator<TosiCarousel>;
134
134
  /** @deprecated Use tosiCarousel instead */
135
135
  export declare const xinCarousel: ElementCreator<TosiCarousel>;
136
+ export {};
package/dist/carousel.js CHANGED
@@ -56,20 +56,19 @@ This is a minimalist carousel component that supports the usual stuff.
56
56
  <tosi-css-var-editor element-selector="tosi-carousel"></tosi-css-var-editor>
57
57
  */
58
58
  /*{ "parent": "Components" }*/
59
- import { Component as WebComponent, elements, vars, } from 'tosijs';
59
+ import { elements, vars, withAttributes } from 'tosijs';
60
60
  import { icons } from './icons.js';
61
61
  const { button, slot, div } = elements;
62
- export class TosiCarousel extends WebComponent {
62
+ export class TosiCarousel extends withAttributes({
63
+ dots: false,
64
+ arrows: false,
65
+ maxVisibleItems: 1,
66
+ snapDuration: 0.25,
67
+ snapDelay: 0.1,
68
+ loop: false,
69
+ auto: 0,
70
+ }) {
63
71
  static preferredTagName = 'tosi-carousel';
64
- static initAttributes = {
65
- dots: false,
66
- arrows: false,
67
- maxVisibleItems: 1,
68
- snapDuration: 0.25,
69
- snapDelay: 0.1,
70
- loop: false,
71
- auto: 0,
72
- };
73
72
  lastAutoAdvance = Date.now();
74
73
  interval;
75
74
  autoAdvance = () => {
@@ -1,11 +1,15 @@
1
- import { Component as WebComponent, ElementCreator, PartsMap } from 'tosijs';
1
+ import { ElementCreator, PartsMap } from 'tosijs';
2
2
  import type { CmHandle, TjsAutocompleteConfig } from './code-editor-cm.js';
3
3
  export type { TjsAutocompleteConfig } from './code-editor-cm.js';
4
4
  interface CodeEditorParts extends PartsMap {
5
5
  host: HTMLDivElement;
6
6
  diffHost: HTMLDivElement;
7
7
  }
8
- export declare class CodeEditor extends WebComponent<CodeEditorParts> {
8
+ declare const CodeEditor_base: import("tosijs").WithAttributes<{
9
+ mode: string;
10
+ disabled: boolean;
11
+ }>;
12
+ export declare class CodeEditor extends CodeEditor_base<CodeEditorParts> {
9
13
  static preferredTagName: string;
10
14
  private source;
11
15
  private _handle;
@@ -34,10 +38,6 @@ export declare class CodeEditor extends WebComponent<CodeEditorParts> {
34
38
  diffOriginalLabel: string;
35
39
  diffModifiedLabel: string;
36
40
  showDiff(on: boolean): void;
37
- static initAttributes: {
38
- mode: string;
39
- disabled: boolean;
40
- };
41
41
  role: string;
42
42
  /**
43
43
  * The underlying CodeMirror `EditorView` (undefined until loaded).
@@ -113,7 +113,7 @@ view. The language, lint and search packages are internal composition details; a
113
113
  one exposed.
114
114
  */
115
115
  /*{ "parent": "Components" }*/
116
- import { Component as WebComponent, elements, varDefault, } from 'tosijs';
116
+ import { elements, varDefault, withAttributes, } from 'tosijs';
117
117
  import { tosiDiff } from './diff.js';
118
118
  const { div } = elements;
119
119
  // Warn once per removed member, not once per access — a live-example page holds
@@ -128,7 +128,10 @@ const warnRemoved = (member, advice) => {
128
128
  // One warning per page, not per element — see the `editor` getter.
129
129
  let warnedEditor = false;
130
130
  let warnedTjs = false;
131
- export class CodeEditor extends WebComponent {
131
+ export class CodeEditor extends withAttributes({
132
+ mode: 'javascript',
133
+ disabled: false,
134
+ }) {
132
135
  static preferredTagName = 'tosi-code';
133
136
  source = '';
134
137
  _handle;
@@ -253,10 +256,6 @@ export class CodeEditor extends WebComponent {
253
256
  }
254
257
  diffHost.hidden = !on;
255
258
  }
256
- static initAttributes = {
257
- mode: 'javascript',
258
- disabled: false,
259
- };
260
259
  role = 'code editor';
261
260
  /**
262
261
  * The underlying CodeMirror `EditorView` (undefined until loaded).