@zeix/le-truc 0.15.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/.ai-context.md +234 -0
- package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
- package/.editorconfig +12 -0
- package/.github/copilot-instructions.md +62 -0
- package/.github/workflows/codeql.yml +108 -0
- package/.github/workflows/static.yml +43 -0
- package/.prettierrc +17 -0
- package/CLAUDE.md +215 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +160 -0
- package/LICENSE +21 -0
- package/README.md +474 -0
- package/biome.json +295 -0
- package/bun.lock +239 -0
- package/docs/about.html +105 -0
- package/docs/assets/main.css +1 -0
- package/docs/assets/main.js +10 -0
- package/docs/assets/main.js.map +66 -0
- package/docs/components.html +293 -0
- package/docs/data-flow.html +308 -0
- package/docs/examples/basic-button.html +367 -0
- package/docs/examples/basic-counter.html +188 -0
- package/docs/examples/basic-hello.html +138 -0
- package/docs/examples/basic-number.html +271 -0
- package/docs/examples/basic-pluralize.html +214 -0
- package/docs/examples/card-callout.html +152 -0
- package/docs/examples/card-mediaqueries.html +138 -0
- package/docs/examples/context-media.html +198 -0
- package/docs/examples/empty.html +37 -0
- package/docs/examples/form-checkbox.html +233 -0
- package/docs/examples/form-combobox.html +420 -0
- package/docs/examples/form-listbox.html +434 -0
- package/docs/examples/form-radiogroup.html +296 -0
- package/docs/examples/form-spinbutton.html +402 -0
- package/docs/examples/form-textbox.html +361 -0
- package/docs/examples/layout.html +67 -0
- package/docs/examples/module-carousel.html +552 -0
- package/docs/examples/module-catalog.html +241 -0
- package/docs/examples/module-codeblock.html +270 -0
- package/docs/examples/module-dialog.html +343 -0
- package/docs/examples/module-lazyload.html +289 -0
- package/docs/examples/module-list.html +197 -0
- package/docs/examples/module-pagination.html +283 -0
- package/docs/examples/module-scrollarea.html +447 -0
- package/docs/examples/module-tabgroup.html +526 -0
- package/docs/examples/module-todo.html +367 -0
- package/docs/examples/module-with-type.html +63 -0
- package/docs/examples/nested-components.html +88 -0
- package/docs/examples/recursive.html +56 -0
- package/docs/examples/simple-text.html +39 -0
- package/docs/examples/snippet.html +93 -0
- package/docs/examples/with-styles.html +75 -0
- package/docs/getting-started.html +143 -0
- package/docs/index.html +112 -0
- package/docs/sitemap.xml +28 -0
- package/docs/styling.html +160 -0
- package/docs/sw.js +112 -0
- package/docs-src/api/README.md +478 -0
- package/docs-src/api/_media/LICENSE +21 -0
- package/docs-src/api/classes/CircularDependencyError.md +299 -0
- package/docs-src/api/classes/CircularMutationError.md +301 -0
- package/docs-src/api/classes/ContextRequestEvent.md +590 -0
- package/docs-src/api/classes/DependencyTimeoutError.md +301 -0
- package/docs-src/api/classes/InvalidCallbackError.md +303 -0
- package/docs-src/api/classes/InvalidComponentNameError.md +295 -0
- package/docs-src/api/classes/InvalidCustomElementError.md +301 -0
- package/docs-src/api/classes/InvalidEffectsError.md +301 -0
- package/docs-src/api/classes/InvalidPropertyNameError.md +307 -0
- package/docs-src/api/classes/InvalidReactivesError.md +307 -0
- package/docs-src/api/classes/InvalidSignalValueError.md +303 -0
- package/docs-src/api/classes/MissingElementError.md +307 -0
- package/docs-src/api/classes/NullishSignalValueError.md +299 -0
- package/docs-src/api/classes/StoreKeyExistsError.md +303 -0
- package/docs-src/api/classes/StoreKeyRangeError.md +299 -0
- package/docs-src/api/classes/StoreKeyReadonlyError.md +303 -0
- package/docs-src/api/functions/asBoolean.md +21 -0
- package/docs-src/api/functions/asEnum.md +31 -0
- package/docs-src/api/functions/asInteger.md +39 -0
- package/docs-src/api/functions/asJSON.md +49 -0
- package/docs-src/api/functions/asNumber.md +37 -0
- package/docs-src/api/functions/asString.md +37 -0
- package/docs-src/api/functions/createCollection.md +83 -0
- package/docs-src/api/functions/createSensor.md +71 -0
- package/docs-src/api/functions/dangerouslySetInnerHTML.md +48 -0
- package/docs-src/api/functions/defineComponent.md +65 -0
- package/docs-src/api/functions/isCollection.md +37 -0
- package/docs-src/api/functions/isParser.md +41 -0
- package/docs-src/api/functions/match.md +47 -0
- package/docs-src/api/functions/on.md +58 -0
- package/docs-src/api/functions/pass.md +53 -0
- package/docs-src/api/functions/provideContexts.md +47 -0
- package/docs-src/api/functions/read.md +47 -0
- package/docs-src/api/functions/requestContext.md +51 -0
- package/docs-src/api/functions/resolve.md +40 -0
- package/docs-src/api/functions/runEffects.md +51 -0
- package/docs-src/api/functions/runElementEffects.md +57 -0
- package/docs-src/api/functions/schedule.md +33 -0
- package/docs-src/api/functions/setAttribute.md +48 -0
- package/docs-src/api/functions/setProperty.md +52 -0
- package/docs-src/api/functions/setStyle.md +48 -0
- package/docs-src/api/functions/setText.md +42 -0
- package/docs-src/api/functions/show.md +42 -0
- package/docs-src/api/functions/toSignal.md +37 -0
- package/docs-src/api/functions/toggleAttribute.md +48 -0
- package/docs-src/api/functions/toggleClass.md +48 -0
- package/docs-src/api/functions/updateElement.md +53 -0
- package/docs-src/api/globals.md +131 -0
- package/docs-src/api/type-aliases/Cleanup.md +27 -0
- package/docs-src/api/type-aliases/Collection.md +91 -0
- package/docs-src/api/type-aliases/CollectionListener.md +27 -0
- package/docs-src/api/type-aliases/Component.md +17 -0
- package/docs-src/api/type-aliases/ComponentProp.md +11 -0
- package/docs-src/api/type-aliases/ComponentProps.md +11 -0
- package/docs-src/api/type-aliases/ComponentSetup.md +31 -0
- package/docs-src/api/type-aliases/ComponentUI.md +27 -0
- package/docs-src/api/type-aliases/Computed.md +49 -0
- package/docs-src/api/type-aliases/ComputedCallback.md +29 -0
- package/docs-src/api/type-aliases/Context.md +33 -0
- package/docs-src/api/type-aliases/ContextType.md +19 -0
- package/docs-src/api/type-aliases/DangerouslySetInnerHTMLOptions.md +27 -0
- package/docs-src/api/type-aliases/DiffResult.md +61 -0
- package/docs-src/api/type-aliases/Effect.md +35 -0
- package/docs-src/api/type-aliases/EffectCallback.md +23 -0
- package/docs-src/api/type-aliases/Effects.md +21 -0
- package/docs-src/api/type-aliases/ElementEffects.md +21 -0
- package/docs-src/api/type-aliases/ElementFromKey.md +21 -0
- package/docs-src/api/type-aliases/ElementQueries.md +27 -0
- package/docs-src/api/type-aliases/ElementUpdater.md +131 -0
- package/docs-src/api/type-aliases/EventHandler.md +31 -0
- package/docs-src/api/type-aliases/EventType.md +17 -0
- package/docs-src/api/type-aliases/Fallback.md +21 -0
- package/docs-src/api/type-aliases/Initializers.md +21 -0
- package/docs-src/api/type-aliases/LooseReader.md +31 -0
- package/docs-src/api/type-aliases/MatchHandlers.md +77 -0
- package/docs-src/api/type-aliases/MaybeCleanup.md +23 -0
- package/docs-src/api/type-aliases/MaybeSignal.md +17 -0
- package/docs-src/api/type-aliases/Parser.md +39 -0
- package/docs-src/api/type-aliases/ParserOrFallback.md +21 -0
- package/docs-src/api/type-aliases/PassedProp.md +25 -0
- package/docs-src/api/type-aliases/PassedProps.md +21 -0
- package/docs-src/api/type-aliases/Reactive.md +25 -0
- package/docs-src/api/type-aliases/Reader.md +31 -0
- package/docs-src/api/type-aliases/ReservedWords.md +11 -0
- package/docs-src/api/type-aliases/ResolveResult.md +29 -0
- package/docs-src/api/type-aliases/SensorEvents.md +25 -0
- package/docs-src/api/type-aliases/Signal.md +41 -0
- package/docs-src/api/type-aliases/State.md +85 -0
- package/docs-src/api/type-aliases/Store.md +29 -0
- package/docs-src/api/type-aliases/UI.md +11 -0
- package/docs-src/api/type-aliases/UnknownContext.md +13 -0
- package/docs-src/api/variables/CONTEXT_REQUEST.md +11 -0
- package/docs-src/api/variables/UNSET.md +23 -0
- package/docs-src/api/variables/batch.md +25 -0
- package/docs-src/api/variables/createComputed.md +41 -0
- package/docs-src/api/variables/createEffect.md +35 -0
- package/docs-src/api/variables/createState.md +37 -0
- package/docs-src/api/variables/createStore.md +42 -0
- package/docs-src/api/variables/diff.md +43 -0
- package/docs-src/api/variables/isAbortError.md +33 -0
- package/docs-src/api/variables/isAsyncFunction.md +39 -0
- package/docs-src/api/variables/isComputed.md +37 -0
- package/docs-src/api/variables/isEqual.md +49 -0
- package/docs-src/api/variables/isFunction.md +39 -0
- package/docs-src/api/variables/isMutableSignal.md +37 -0
- package/docs-src/api/variables/isNumber.md +33 -0
- package/docs-src/api/variables/isRecord.md +39 -0
- package/docs-src/api/variables/isRecordOrArray.md +39 -0
- package/docs-src/api/variables/isSignal.md +37 -0
- package/docs-src/api/variables/isState.md +37 -0
- package/docs-src/api/variables/isStore.md +37 -0
- package/docs-src/api/variables/isString.md +33 -0
- package/docs-src/api/variables/isSymbol.md +33 -0
- package/docs-src/api/variables/toError.md +33 -0
- package/docs-src/api/variables/valueString.md +33 -0
- package/docs-src/includes/menu.html +44 -0
- package/docs-src/pages/about.md +89 -0
- package/docs-src/pages/components.md +437 -0
- package/docs-src/pages/data-flow.md +449 -0
- package/docs-src/pages/getting-started.md +170 -0
- package/docs-src/pages/index.md +98 -0
- package/docs-src/pages/styling.md +165 -0
- package/eslint.config.js +64 -0
- package/examples/_common/clear.ts +49 -0
- package/examples/_common/fetch.ts +160 -0
- package/examples/_common/focus.ts +45 -0
- package/examples/_common/highlight.ts +5 -0
- package/examples/_global.css +463 -0
- package/examples/basic-button/basic-button.css +176 -0
- package/examples/basic-button/basic-button.html +46 -0
- package/examples/basic-button/basic-button.spec.ts +160 -0
- package/examples/basic-button/basic-button.ts +45 -0
- package/examples/basic-button/copyToClipboard.ts +37 -0
- package/examples/basic-counter/basic-counter.css +21 -0
- package/examples/basic-counter/basic-counter.html +24 -0
- package/examples/basic-counter/basic-counter.spec.ts +85 -0
- package/examples/basic-counter/basic-counter.ts +43 -0
- package/examples/basic-hello/basic-hello.html +34 -0
- package/examples/basic-hello/basic-hello.spec.ts +110 -0
- package/examples/basic-hello/basic-hello.ts +36 -0
- package/examples/basic-number/basic-number.html +79 -0
- package/examples/basic-number/basic-number.spec.ts +175 -0
- package/examples/basic-number/basic-number.ts +124 -0
- package/examples/basic-pluralize/basic-pluralize.html +64 -0
- package/examples/basic-pluralize/basic-pluralize.spec.ts +258 -0
- package/examples/basic-pluralize/basic-pluralize.ts +82 -0
- package/examples/card-callout/card-callout.css +79 -0
- package/examples/card-callout/card-callout.html +5 -0
- package/examples/card-mediaqueries/card-mediaqueries.html +29 -0
- package/examples/card-mediaqueries/card-mediaqueries.spec.ts +300 -0
- package/examples/card-mediaqueries/card-mediaqueries.ts +41 -0
- package/examples/context-media/context-media.html +3 -0
- package/examples/context-media/context-media.ts +127 -0
- package/examples/form-checkbox/form-checkbox.css +70 -0
- package/examples/form-checkbox/form-checkbox.html +13 -0
- package/examples/form-checkbox/form-checkbox.spec.ts +357 -0
- package/examples/form-checkbox/form-checkbox.ts +50 -0
- package/examples/form-checkbox/vanilla-checkbox.ts +101 -0
- package/examples/form-combobox/form-combobox.css +118 -0
- package/examples/form-combobox/form-combobox.html +74 -0
- package/examples/form-combobox/form-combobox.spec.ts +977 -0
- package/examples/form-combobox/form-combobox.ts +128 -0
- package/examples/form-listbox/form-listbox.css +71 -0
- package/examples/form-listbox/form-listbox.html +67 -0
- package/examples/form-listbox/form-listbox.spec.ts +1050 -0
- package/examples/form-listbox/form-listbox.ts +196 -0
- package/examples/form-listbox/mocks/timezones.json +495 -0
- package/examples/form-radiogroup/form-radiogroup.css +87 -0
- package/examples/form-radiogroup/form-radiogroup.html +51 -0
- package/examples/form-radiogroup/form-radiogroup.spec.ts +515 -0
- package/examples/form-radiogroup/form-radiogroup.ts +58 -0
- package/examples/form-spinbutton/form-spinbutton.css +95 -0
- package/examples/form-spinbutton/form-spinbutton.html +96 -0
- package/examples/form-spinbutton/form-spinbutton.spec.ts +688 -0
- package/examples/form-spinbutton/form-spinbutton.ts +111 -0
- package/examples/form-textbox/form-textbox.css +104 -0
- package/examples/form-textbox/form-textbox.html +53 -0
- package/examples/form-textbox/form-textbox.spec.ts +542 -0
- package/examples/form-textbox/form-textbox.ts +104 -0
- package/examples/main.css +22 -0
- package/examples/main.ts +23 -0
- package/examples/module-carousel/module-carousel.css +113 -0
- package/examples/module-carousel/module-carousel.html +208 -0
- package/examples/module-carousel/module-carousel.spec.ts +523 -0
- package/examples/module-carousel/module-carousel.ts +131 -0
- package/examples/module-catalog/module-catalog.css +22 -0
- package/examples/module-catalog/module-catalog.html +82 -0
- package/examples/module-catalog/module-catalog.spec.ts +396 -0
- package/examples/module-catalog/module-catalog.ts +37 -0
- package/examples/module-codeblock/module-codeblock.css +95 -0
- package/examples/module-codeblock/module-codeblock.html +28 -0
- package/examples/module-codeblock/module-codeblock.ts +47 -0
- package/examples/module-demo/module-demo.css +13 -0
- package/examples/module-dialog/module-dialog.css +96 -0
- package/examples/module-dialog/module-dialog.html +66 -0
- package/examples/module-dialog/module-dialog.spec.ts +557 -0
- package/examples/module-dialog/module-dialog.ts +81 -0
- package/examples/module-lazyload/mocks/empty.html +1 -0
- package/examples/module-lazyload/mocks/module-with-type.html +27 -0
- package/examples/module-lazyload/mocks/nested-components.html +52 -0
- package/examples/module-lazyload/mocks/recursive.html +20 -0
- package/examples/module-lazyload/mocks/simple-text.html +3 -0
- package/examples/module-lazyload/mocks/snippet.html +57 -0
- package/examples/module-lazyload/mocks/with-styles.html +39 -0
- package/examples/module-lazyload/module-lazyload.html +132 -0
- package/examples/module-lazyload/module-lazyload.spec.ts +734 -0
- package/examples/module-lazyload/module-lazyload.ts +89 -0
- package/examples/module-list/module-list.html +30 -0
- package/examples/module-list/module-list.spec.ts +592 -0
- package/examples/module-list/module-list.ts +99 -0
- package/examples/module-pagination/module-pagination.css +79 -0
- package/examples/module-pagination/module-pagination.html +16 -0
- package/examples/module-pagination/module-pagination.spec.ts +701 -0
- package/examples/module-pagination/module-pagination.ts +88 -0
- package/examples/module-scrollarea/module-scrollarea.css +77 -0
- package/examples/module-scrollarea/module-scrollarea.html +189 -0
- package/examples/module-scrollarea/module-scrollarea.spec.ts +445 -0
- package/examples/module-scrollarea/module-scrollarea.ts +81 -0
- package/examples/module-tabgroup/module-tabgroup.css +55 -0
- package/examples/module-tabgroup/module-tabgroup.html +269 -0
- package/examples/module-tabgroup/module-tabgroup.spec.ts +631 -0
- package/examples/module-tabgroup/module-tabgroup.ts +102 -0
- package/examples/module-toc/module-toc.css +34 -0
- package/examples/module-todo/module-todo.css +84 -0
- package/examples/module-todo/module-todo.html +92 -0
- package/examples/module-todo/module-todo.spec.ts +528 -0
- package/examples/module-todo/module-todo.ts +91 -0
- package/examples/section-hero/section-hero.css +37 -0
- package/examples/section-menu/section-menu.css +81 -0
- package/examples/server.ts +95 -0
- package/examples/test-setup.md +314 -0
- package/index.dev.js +1688 -0
- package/index.dev.ts +127 -0
- package/index.js +3 -0
- package/index.js.map +42 -0
- package/index.ts +127 -0
- package/package.json +64 -0
- package/playwright.config.ts +31 -0
- package/server/BUILD_SYSTEM.md +428 -0
- package/server/SERVER.md +286 -0
- package/server/build.ts +91 -0
- package/server/config.ts +130 -0
- package/server/effects/api.ts +28 -0
- package/server/effects/css.ts +31 -0
- package/server/effects/examples.ts +109 -0
- package/server/effects/js.ts +32 -0
- package/server/effects/menu.ts +34 -0
- package/server/effects/pages.ts +178 -0
- package/server/effects/service-worker.ts +57 -0
- package/server/effects/sitemap.ts +27 -0
- package/server/file-signals.ts +361 -0
- package/server/file-watcher.ts +77 -0
- package/server/io.ts +174 -0
- package/server/layout-engine.ts +470 -0
- package/server/layout-utils.ts +615 -0
- package/server/layouts/api.html +76 -0
- package/server/layouts/base.html +37 -0
- package/server/layouts/blog.html +115 -0
- package/server/layouts/example.html +104 -0
- package/server/layouts/overview.html +165 -0
- package/server/layouts/page.html +36 -0
- package/server/layouts/test.html +24 -0
- package/server/markdoc-helpers.ts +217 -0
- package/server/markdoc.config.ts +29 -0
- package/server/schema/callout.markdoc.ts +17 -0
- package/server/schema/carousel.markdoc.ts +118 -0
- package/server/schema/demo.markdoc.ts +74 -0
- package/server/schema/fence.markdoc.ts +84 -0
- package/server/schema/heading.markdoc.ts +23 -0
- package/server/schema/hero.markdoc.ts +59 -0
- package/server/schema/section.markdoc.ts +10 -0
- package/server/schema/slide.markdoc.ts +17 -0
- package/server/schema/source.markdoc.ts +53 -0
- package/server/schema/tabgroup.markdoc.ts +102 -0
- package/server/serve.ts +635 -0
- package/server/templates/README.md +352 -0
- package/server/templates/constants.ts +236 -0
- package/server/templates/fragments.ts +159 -0
- package/server/templates/hmr.ts +269 -0
- package/server/templates/menu.ts +33 -0
- package/server/templates/performance-hints.ts +94 -0
- package/server/templates/service-worker.ts +403 -0
- package/server/templates/sitemap.ts +57 -0
- package/server/templates/toc.ts +41 -0
- package/server/templates/utils.ts +378 -0
- package/src/component.ts +215 -0
- package/src/context.ts +156 -0
- package/src/effects/attribute.ts +82 -0
- package/src/effects/class.ts +28 -0
- package/src/effects/event.ts +67 -0
- package/src/effects/html.ts +60 -0
- package/src/effects/method.ts +57 -0
- package/src/effects/pass.ts +103 -0
- package/src/effects/property.ts +57 -0
- package/src/effects/style.ts +34 -0
- package/src/effects/text.ts +28 -0
- package/src/effects.ts +412 -0
- package/src/errors.ts +160 -0
- package/src/parsers/boolean.ts +14 -0
- package/src/parsers/json.ts +33 -0
- package/src/parsers/number.ts +55 -0
- package/src/parsers/string.ts +32 -0
- package/src/parsers.ts +90 -0
- package/src/scheduler.ts +47 -0
- package/src/signals/collection.ts +253 -0
- package/src/signals/sensor.ts +131 -0
- package/src/ui.ts +236 -0
- package/src/util.ts +187 -0
- package/tsconfig.json +34 -0
- package/types/examples/basic-button/basic-button.d.ts +16 -0
- package/types/examples/basic-hello/basic-hello.d.ts +18 -0
- package/types/index.d.ts +27 -0
- package/types/index.dev.d.ts +27 -0
- package/types/src/collection.d.ts +27 -0
- package/types/src/component.d.ts +32 -0
- package/types/src/context.d.ts +85 -0
- package/types/src/effects/attribute.d.ts +23 -0
- package/types/src/effects/callMethod.d.ts +23 -0
- package/types/src/effects/class.d.ts +13 -0
- package/types/src/effects/dangerouslySetInnerHTML.d.ts +18 -0
- package/types/src/effects/event.d.ts +18 -0
- package/types/src/effects/html.d.ts +17 -0
- package/types/src/effects/method.d.ts +22 -0
- package/types/src/effects/pass.d.ts +18 -0
- package/types/src/effects/property.d.ts +22 -0
- package/types/src/effects/setAttribute.d.ts +24 -0
- package/types/src/effects/setProperty.d.ts +23 -0
- package/types/src/effects/setStyle.d.ts +14 -0
- package/types/src/effects/setText.d.ts +13 -0
- package/types/src/effects/style.d.ts +13 -0
- package/types/src/effects/text.d.ts +12 -0
- package/types/src/effects/toggleClass.d.ts +14 -0
- package/types/src/effects.d.ts +153 -0
- package/types/src/errors.d.ts +99 -0
- package/types/src/events.d.ts +27 -0
- package/types/src/extractors.d.ts +23 -0
- package/types/src/parsers/boolean.d.ts +10 -0
- package/types/src/parsers/json.d.ts +13 -0
- package/types/src/parsers/number.d.ts +21 -0
- package/types/src/parsers/string.d.ts +19 -0
- package/types/src/parsers.d.ts +41 -0
- package/types/src/scheduler.d.ts +11 -0
- package/types/src/sensor.d.ts +27 -0
- package/types/src/signals/collection.d.ts +32 -0
- package/types/src/signals/sensor.d.ts +27 -0
- package/types/src/ui.d.ts +37 -0
- package/types/src/util.d.ts +65 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
|
|
7
|
+
<!-- Page title/description (child layouts may override the title when extending) -->
|
|
8
|
+
<title>{{ title }} – Le Truc Docs</title>
|
|
9
|
+
<meta name="description" content="{{ description }}" />
|
|
10
|
+
|
|
11
|
+
<!-- Core assets (server provides `base-path`, `css-hash` and `js-hash`) -->
|
|
12
|
+
<link
|
|
13
|
+
rel="preload"
|
|
14
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
15
|
+
as="style"
|
|
16
|
+
/>
|
|
17
|
+
<link
|
|
18
|
+
rel="modulepreload"
|
|
19
|
+
href="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
20
|
+
/>
|
|
21
|
+
<link
|
|
22
|
+
rel="stylesheet"
|
|
23
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
24
|
+
/>
|
|
25
|
+
<script
|
|
26
|
+
type="module"
|
|
27
|
+
src="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
28
|
+
></script>
|
|
29
|
+
|
|
30
|
+
<!-- Additional per-layout head fragment injected by child layouts -->
|
|
31
|
+
{{ head }}
|
|
32
|
+
</head>
|
|
33
|
+
|
|
34
|
+
<body class="{{ section }} {{ body-class }}">
|
|
35
|
+
{{ content }}
|
|
36
|
+
</body>
|
|
37
|
+
</html>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{ title }} – Le Truc Blog</title>
|
|
7
|
+
<meta name="description" content="{{ description }}" />
|
|
8
|
+
<meta name="author" content="{{ author }}" />
|
|
9
|
+
<meta name="article:published_time" content="{{ published-date }}" />
|
|
10
|
+
<meta name="article:modified_time" content="{{ modified-date }}" />
|
|
11
|
+
<link
|
|
12
|
+
rel="preload"
|
|
13
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
14
|
+
as="style"
|
|
15
|
+
/>
|
|
16
|
+
<link
|
|
17
|
+
rel="modulepreload"
|
|
18
|
+
href="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
19
|
+
/>
|
|
20
|
+
<link
|
|
21
|
+
rel="stylesheet"
|
|
22
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
23
|
+
/>
|
|
24
|
+
<script
|
|
25
|
+
type="module"
|
|
26
|
+
src="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
27
|
+
></script>
|
|
28
|
+
</head>
|
|
29
|
+
<body class="blog">
|
|
30
|
+
<context-router>
|
|
31
|
+
<header class="content-grid">
|
|
32
|
+
<a href="#main" class="skiplink visually-hidden">
|
|
33
|
+
Skip to main content
|
|
34
|
+
</a>
|
|
35
|
+
<h1 class="content">Le Truc Docs <small>Version 0.15.0</small></h1>
|
|
36
|
+
{{ include 'menu.html' }}
|
|
37
|
+
<card-callout class="content danger" hidden>
|
|
38
|
+
<p class="error" role="alert" aria-live="assertive"></p>
|
|
39
|
+
</card-callout>
|
|
40
|
+
</header>
|
|
41
|
+
<div class="blog-header">
|
|
42
|
+
<div class="content-grid">
|
|
43
|
+
<div class="content">
|
|
44
|
+
<h1 class="blog-title">{{ title }}</h1>
|
|
45
|
+
<p class="blog-subtitle">{{ description }}</p>
|
|
46
|
+
<div class="blog-meta">
|
|
47
|
+
<div class="blog-meta-item">
|
|
48
|
+
<span>📅</span>
|
|
49
|
+
<time datetime="{{ published-date }}">{{ published-date-formatted }}</time>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="blog-meta-item">
|
|
52
|
+
<span></span>👤</span>
|
|
53
|
+
<span>{{ author }}</span>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="blog-meta-item">
|
|
56
|
+
<span>⏱</span>
|
|
57
|
+
<span>{{ reading-time }} min read</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="blog-tags">
|
|
61
|
+
{{ blog-tags }}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<main id="main" class="content-grid">
|
|
67
|
+
<div class="content">
|
|
68
|
+
<div class="grid" style="grid-template-columns: 1fr 300px; gap: 2rem;">
|
|
69
|
+
<div class="blog-content">
|
|
70
|
+
<article>
|
|
71
|
+
{{ content }}
|
|
72
|
+
</article>
|
|
73
|
+
<div class="blog-author">
|
|
74
|
+
<img src="{{ author-avatar }}" alt="{{ author }}" class="blog-author-avatar" />
|
|
75
|
+
<div class="blog-author-info">
|
|
76
|
+
<h3>{{ author }}</h3>
|
|
77
|
+
<p class="blog-author-bio">{{ author-bio }}</p>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<aside class="blog-toc">
|
|
82
|
+
<h3>Table of Contents</h3>
|
|
83
|
+
{{ toc }}
|
|
84
|
+
</aside>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</main>
|
|
88
|
+
<div class="blog-nav">
|
|
89
|
+
<div class="content-grid">
|
|
90
|
+
<div class="content">
|
|
91
|
+
<nav class="blog-nav-links" aria-label="Blog navigation">
|
|
92
|
+
<a href="{{ prev-post }}" class="blog-nav-link prev">
|
|
93
|
+
<span class="blog-nav-label">← Previous</span>
|
|
94
|
+
<span class="blog-nav-title">{{ prev-post-title }}</span>
|
|
95
|
+
</a>
|
|
96
|
+
<a href="/blog/" class="blog-nav-link">
|
|
97
|
+
📋 All Posts
|
|
98
|
+
</a>
|
|
99
|
+
<a href="{{ next-post }}" class="blog-nav-link next">
|
|
100
|
+
<span class="blog-nav-label">Next →</span>
|
|
101
|
+
<span class="blog-nav-title">{{ next-post-title }}</span>
|
|
102
|
+
</a>
|
|
103
|
+
</nav>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
<footer class="content-grid">
|
|
108
|
+
<div class="content">
|
|
109
|
+
<h2 class="visually-hidden">Footer</h2>
|
|
110
|
+
<p>© 2024 – 2025 Zeix AG</p>
|
|
111
|
+
</div>
|
|
112
|
+
</footer>
|
|
113
|
+
</context-router>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{ title }} – Le Truc Examples</title>
|
|
7
|
+
<meta name="description" content="{{ description }}" />
|
|
8
|
+
<link
|
|
9
|
+
rel="preload"
|
|
10
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
11
|
+
as="style"
|
|
12
|
+
/>
|
|
13
|
+
<link
|
|
14
|
+
rel="modulepreload"
|
|
15
|
+
href="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
16
|
+
/>
|
|
17
|
+
<link
|
|
18
|
+
rel="stylesheet"
|
|
19
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
20
|
+
/>
|
|
21
|
+
<script
|
|
22
|
+
type="module"
|
|
23
|
+
src="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
24
|
+
></script>
|
|
25
|
+
</head>
|
|
26
|
+
<body class="example">
|
|
27
|
+
<context-router>
|
|
28
|
+
<header class="content-grid">
|
|
29
|
+
<a href="#main" class="skiplink visually-hidden">
|
|
30
|
+
Skip to main content
|
|
31
|
+
</a>
|
|
32
|
+
<h1 class="content">Le Truc Docs <small>Version 0.15.0</small></h1>
|
|
33
|
+
{{ include 'menu.html' }}
|
|
34
|
+
<card-callout class="content danger" hidden>
|
|
35
|
+
<p class="error" role="alert" aria-live="assertive"></p>
|
|
36
|
+
</card-callout>
|
|
37
|
+
</header>
|
|
38
|
+
<div class="example-header">
|
|
39
|
+
<div class="content-grid">
|
|
40
|
+
<div class="content">
|
|
41
|
+
<h1 class="example-title">{{ example-name }}</h1>
|
|
42
|
+
<p class="example-subtitle">{{ example-description }}</p>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="example-meta">
|
|
47
|
+
<div class="content-grid">
|
|
48
|
+
<div class="content">
|
|
49
|
+
<div class="example-tags">
|
|
50
|
+
<span
|
|
51
|
+
class="example-tag example-difficulty {{ example-difficulty }}"
|
|
52
|
+
>{{ example-difficulty }}</span
|
|
53
|
+
>
|
|
54
|
+
{{ example-tags }}
|
|
55
|
+
</div>
|
|
56
|
+
<div class="example-actions">
|
|
57
|
+
<a
|
|
58
|
+
href="/test/{{ example-slug }}.html"
|
|
59
|
+
class="example-action primary"
|
|
60
|
+
>
|
|
61
|
+
▶ Live Demo
|
|
62
|
+
</a>
|
|
63
|
+
<a
|
|
64
|
+
href="{{ example-source }}"
|
|
65
|
+
class="example-action secondary"
|
|
66
|
+
target="_blank"
|
|
67
|
+
rel="noopener"
|
|
68
|
+
>
|
|
69
|
+
📄 View Source
|
|
70
|
+
</a>
|
|
71
|
+
{{ example-actions }}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<main id="main" class="content-grid">
|
|
77
|
+
<div class="content example-content">{{ content }}</div>
|
|
78
|
+
</main>
|
|
79
|
+
<div class="example-nav">
|
|
80
|
+
<div class="content-grid">
|
|
81
|
+
<div class="content">
|
|
82
|
+
<nav class="example-nav-links" aria-label="Example navigation">
|
|
83
|
+
<a href="{{ prev-example }}" class="example-nav-link">
|
|
84
|
+
← {{ prev-example-title }}
|
|
85
|
+
</a>
|
|
86
|
+
<a href="/examples/" class="example-nav-link">
|
|
87
|
+
📋 All Examples
|
|
88
|
+
</a>
|
|
89
|
+
<a href="{{ next-example }}" class="example-nav-link">
|
|
90
|
+
{{ next-example-title }} →
|
|
91
|
+
</a>
|
|
92
|
+
</nav>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<footer class="content-grid">
|
|
97
|
+
<div class="content">
|
|
98
|
+
<h2 class="visually-hidden">Footer</h2>
|
|
99
|
+
<p>© 2024 – 2025 Zeix AG</p>
|
|
100
|
+
</div>
|
|
101
|
+
</footer>
|
|
102
|
+
</context-router>
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{ title }} – Le Truc Docs</title>
|
|
7
|
+
<meta name="description" content="{{ description }}" />
|
|
8
|
+
<link
|
|
9
|
+
rel="preload"
|
|
10
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
11
|
+
as="style"
|
|
12
|
+
/>
|
|
13
|
+
<link
|
|
14
|
+
rel="modulepreload"
|
|
15
|
+
href="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
16
|
+
/>
|
|
17
|
+
<link
|
|
18
|
+
rel="stylesheet"
|
|
19
|
+
href="{{ base-path }}assets/main.css?v={{ css-hash }}"
|
|
20
|
+
/>
|
|
21
|
+
<script
|
|
22
|
+
type="module"
|
|
23
|
+
src="{{ base-path }}assets/main.js?v={{ js-hash }}"
|
|
24
|
+
></script>
|
|
25
|
+
</head>
|
|
26
|
+
<body class="{{ section }} overview">
|
|
27
|
+
<context-router>
|
|
28
|
+
<header class="content-grid">
|
|
29
|
+
<a href="#main" class="skiplink visually-hidden">
|
|
30
|
+
Skip to main content
|
|
31
|
+
</a>
|
|
32
|
+
<h1 class="content">Le Truc Docs <small>Version 0.15.0</small></h1>
|
|
33
|
+
{{ include 'menu.html' }}
|
|
34
|
+
<card-callout class="content danger" hidden>
|
|
35
|
+
<p class="error" role="alert" aria-live="assertive"></p>
|
|
36
|
+
</card-callout>
|
|
37
|
+
</header>
|
|
38
|
+
<div class="overview-header">
|
|
39
|
+
<div class="content-grid">
|
|
40
|
+
<div class="content">
|
|
41
|
+
<h1 class="overview-title">{{ overview-title }}</h1>
|
|
42
|
+
<p class="overview-subtitle">{{ overview-description }}</p>
|
|
43
|
+
<div class="overview-stats">{{ overview-stats }}</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="overview-filters">
|
|
48
|
+
<div class="content-grid">
|
|
49
|
+
<div class="content">
|
|
50
|
+
<div class="overview-filter-bar">
|
|
51
|
+
<input
|
|
52
|
+
type="search"
|
|
53
|
+
class="overview-search"
|
|
54
|
+
placeholder="{{ search-placeholder }}"
|
|
55
|
+
aria-label="Search {{ overview-type }}"
|
|
56
|
+
/>
|
|
57
|
+
<select
|
|
58
|
+
class="overview-filter-select"
|
|
59
|
+
aria-label="Filter by category"
|
|
60
|
+
>
|
|
61
|
+
<option value="">All Categories</option>
|
|
62
|
+
{{ filter-options }}
|
|
63
|
+
</select>
|
|
64
|
+
<div class="overview-sort">
|
|
65
|
+
<span>Sort:</span>
|
|
66
|
+
<button class="overview-sort-btn active" data-sort="name">
|
|
67
|
+
Name
|
|
68
|
+
</button>
|
|
69
|
+
<button class="overview-sort-btn" data-sort="date">Date</button>
|
|
70
|
+
<button class="overview-sort-btn" data-sort="popularity">
|
|
71
|
+
Popular
|
|
72
|
+
</button>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
<main id="main" class="content-grid">
|
|
79
|
+
<div class="content overview-content">
|
|
80
|
+
<div class="overview-grid" id="overview-grid">{{ content }}</div>
|
|
81
|
+
<div class="overview-empty" id="overview-empty" style="display: none">
|
|
82
|
+
<div class="overview-empty-icon">🔍</div>
|
|
83
|
+
<h3>No results found</h3>
|
|
84
|
+
<p>Try adjusting your search or filter criteria.</p>
|
|
85
|
+
</div>
|
|
86
|
+
<nav class="overview-pagination" aria-label="Pagination">
|
|
87
|
+
{{ pagination }}
|
|
88
|
+
</nav>
|
|
89
|
+
</div>
|
|
90
|
+
</main>
|
|
91
|
+
<footer class="content-grid">
|
|
92
|
+
<div class="content">
|
|
93
|
+
<h2 class="visually-hidden">Footer</h2>
|
|
94
|
+
<p>© 2024 – 2025 Zeix AG</p>
|
|
95
|
+
</div>
|
|
96
|
+
</footer>
|
|
97
|
+
</context-router>
|
|
98
|
+
<script>
|
|
99
|
+
// Simple search and filter functionality
|
|
100
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
101
|
+
const searchInput = document.querySelector('.overview-search')
|
|
102
|
+
const filterSelect = document.querySelector('.overview-filter-select')
|
|
103
|
+
const sortBtns = document.querySelectorAll('.overview-sort-btn')
|
|
104
|
+
const grid = document.getElementById('overview-grid')
|
|
105
|
+
const empty = document.getElementById('overview-empty')
|
|
106
|
+
const cards = Array.from(grid.querySelectorAll('.overview-card'))
|
|
107
|
+
|
|
108
|
+
function filterAndSort() {
|
|
109
|
+
const searchTerm = searchInput.value.toLowerCase()
|
|
110
|
+
const filterValue = filterSelect.value
|
|
111
|
+
const sortValue = document.querySelector('.overview-sort-btn.active')
|
|
112
|
+
.dataset.sort
|
|
113
|
+
|
|
114
|
+
let visibleCards = cards.filter(card => {
|
|
115
|
+
const title = card
|
|
116
|
+
.querySelector('.overview-card-title')
|
|
117
|
+
.textContent.toLowerCase()
|
|
118
|
+
const description = card
|
|
119
|
+
.querySelector('.overview-card-description')
|
|
120
|
+
.textContent.toLowerCase()
|
|
121
|
+
const matchesSearch =
|
|
122
|
+
!searchTerm
|
|
123
|
+
|| title.includes(searchTerm)
|
|
124
|
+
|| description.includes(searchTerm)
|
|
125
|
+
|
|
126
|
+
const category = card.dataset.category || ''
|
|
127
|
+
const matchesFilter = !filterValue || category === filterValue
|
|
128
|
+
|
|
129
|
+
return matchesSearch && matchesFilter
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
// Sort cards
|
|
133
|
+
visibleCards.sort((a, b) => {
|
|
134
|
+
const aValue =
|
|
135
|
+
a.dataset[sortValue]
|
|
136
|
+
|| a.querySelector('.overview-card-title').textContent
|
|
137
|
+
const bValue =
|
|
138
|
+
b.dataset[sortValue]
|
|
139
|
+
|| b.querySelector('.overview-card-title').textContent
|
|
140
|
+
return aValue.localeCompare(bValue)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Show/hide cards
|
|
144
|
+
cards.forEach(card => {
|
|
145
|
+
card.style.display = visibleCards.includes(card) ? '' : 'none'
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
// Show/hide empty state
|
|
149
|
+
empty.style.display = visibleCards.length === 0 ? '' : 'none'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
searchInput.addEventListener('input', filterAndSort)
|
|
153
|
+
filterSelect.addEventListener('change', filterAndSort)
|
|
154
|
+
|
|
155
|
+
sortBtns.forEach(btn => {
|
|
156
|
+
btn.addEventListener('click', function () {
|
|
157
|
+
sortBtns.forEach(b => b.classList.remove('active'))
|
|
158
|
+
this.classList.add('active')
|
|
159
|
+
filterAndSort()
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
</script>
|
|
164
|
+
</body>
|
|
165
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{{ extends 'base.html' }}
|
|
2
|
+
|
|
3
|
+
<head>
|
|
4
|
+
<title>{{ title }} – Le Truc Docs</title>
|
|
5
|
+
<meta name="description" content="{{ description }}" />
|
|
6
|
+
</head>
|
|
7
|
+
|
|
8
|
+
<body class="{{ section }} {{ body-class }}">
|
|
9
|
+
<a href="#main" class="skiplink visually-hidden">Skip to main content</a>
|
|
10
|
+
|
|
11
|
+
<context-router>
|
|
12
|
+
<header class="content-grid">
|
|
13
|
+
<h1 class="content">Le Truc Docs <small>Version 0.15.0</small></h1>
|
|
14
|
+
|
|
15
|
+
<!-- Optional shared navigation include -->
|
|
16
|
+
{{ include 'menu.html' }}
|
|
17
|
+
|
|
18
|
+
<!-- Page-level callout used by client scripts (hidden by default) -->
|
|
19
|
+
<card-callout class="content danger" hidden>
|
|
20
|
+
<p class="error" role="alert" aria-live="assertive"></p>
|
|
21
|
+
</card-callout>
|
|
22
|
+
</header>
|
|
23
|
+
|
|
24
|
+
<main id="main" class="content-grid">
|
|
25
|
+
<!-- Rendered page content or child-layout inner body -->
|
|
26
|
+
{{ content }}
|
|
27
|
+
</main>
|
|
28
|
+
|
|
29
|
+
<footer class="content-grid">
|
|
30
|
+
<div class="content">
|
|
31
|
+
<h2 class="visually-hidden">Footer</h2>
|
|
32
|
+
<p>© 2024 – 2025 Zeix AG</p>
|
|
33
|
+
</div>
|
|
34
|
+
</footer>
|
|
35
|
+
</context-router>
|
|
36
|
+
</body>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{{ extends 'base.html' }}
|
|
2
|
+
|
|
3
|
+
<head>
|
|
4
|
+
<title>{{ title }} – Le Truc Component Test</title>
|
|
5
|
+
<meta name="description" content="Testing {{ component-name }} component" />
|
|
6
|
+
</head>
|
|
7
|
+
|
|
8
|
+
<body class="test">
|
|
9
|
+
<header class="content-grid">
|
|
10
|
+
<a href="#main" class="skiplink visually-hidden">Skip to main content</a>
|
|
11
|
+
<h1 class="content">{{ title }} <small>Le Truc 0.15.0</small></h1>
|
|
12
|
+
<card-callout class="content danger" hidden>
|
|
13
|
+
<p class="error" role="alert" aria-live="assertive"></p>
|
|
14
|
+
</card-callout>
|
|
15
|
+
</header>
|
|
16
|
+
<main id="main" class="content-grid">
|
|
17
|
+
<section class="content">{{content}}</section>
|
|
18
|
+
</main>
|
|
19
|
+
<footer class="content-grid">
|
|
20
|
+
<div class="content">
|
|
21
|
+
<h2 class="visually-hidden">Footer</h2>
|
|
22
|
+
</div>
|
|
23
|
+
</footer>
|
|
24
|
+
</body>
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import Markdoc, {
|
|
2
|
+
type Node,
|
|
3
|
+
type RenderableTreeNode,
|
|
4
|
+
Tag,
|
|
5
|
+
} from '@markdoc/markdoc'
|
|
6
|
+
import markdocConfig from './markdoc.config'
|
|
7
|
+
import { generateSlug as templateSlug } from './templates/utils'
|
|
8
|
+
|
|
9
|
+
// Common attribute definitions for reuse across schemas
|
|
10
|
+
export const classAttribute = {
|
|
11
|
+
type: String,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const idAttribute = {
|
|
15
|
+
type: String,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const styleAttribute = {
|
|
19
|
+
type: String,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const titleAttribute = {
|
|
23
|
+
type: String,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const requiredTitleAttribute = {
|
|
27
|
+
type: String,
|
|
28
|
+
required: true,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Common children arrays for different content types
|
|
32
|
+
export const standardChildren = [
|
|
33
|
+
'paragraph',
|
|
34
|
+
'heading',
|
|
35
|
+
'list',
|
|
36
|
+
'blockquote',
|
|
37
|
+
'hr',
|
|
38
|
+
'fence',
|
|
39
|
+
'callout',
|
|
40
|
+
'tag',
|
|
41
|
+
'inline',
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
export const richChildren = [
|
|
45
|
+
'paragraph',
|
|
46
|
+
'heading',
|
|
47
|
+
'list',
|
|
48
|
+
'item',
|
|
49
|
+
'blockquote',
|
|
50
|
+
'hr',
|
|
51
|
+
'fence',
|
|
52
|
+
'callout',
|
|
53
|
+
'tag',
|
|
54
|
+
'inline',
|
|
55
|
+
'text',
|
|
56
|
+
'strong',
|
|
57
|
+
'em',
|
|
58
|
+
'code',
|
|
59
|
+
'link',
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
// Common attribute sets
|
|
63
|
+
export const commonAttributes = {
|
|
64
|
+
class: classAttribute,
|
|
65
|
+
id: idAttribute,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const styledAttributes = {
|
|
69
|
+
...commonAttributes,
|
|
70
|
+
style: styleAttribute,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Text extraction utility used by multiple schemas
|
|
74
|
+
export function extractTextFromNode(node: Node): string {
|
|
75
|
+
if (node.type === 'text') {
|
|
76
|
+
return node.attributes.content || ''
|
|
77
|
+
}
|
|
78
|
+
if (node.children) {
|
|
79
|
+
return node.children.map(extractTextFromNode).join('')
|
|
80
|
+
}
|
|
81
|
+
return ''
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Transform child nodes with markdoc config
|
|
85
|
+
export function transformChildrenWithConfig(
|
|
86
|
+
children: Node[],
|
|
87
|
+
): RenderableTreeNode[] {
|
|
88
|
+
return children.map((child: Node) => Markdoc.transform(child, markdocConfig))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Split content by separator nodes (used by carousel, tabgroup, demo)
|
|
92
|
+
export function splitContentBySeparator(
|
|
93
|
+
children: Node[],
|
|
94
|
+
separatorType: string = 'hr',
|
|
95
|
+
): Node[][] {
|
|
96
|
+
const sections: Node[][] = []
|
|
97
|
+
let currentSection: Node[] = []
|
|
98
|
+
|
|
99
|
+
for (const child of children) {
|
|
100
|
+
if (child.type === separatorType) {
|
|
101
|
+
if (currentSection.length > 0) {
|
|
102
|
+
sections.push(currentSection)
|
|
103
|
+
currentSection = []
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
currentSection.push(child)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Add the last section if it has content
|
|
111
|
+
if (currentSection.length > 0) {
|
|
112
|
+
sections.push(currentSection)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return sections
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Generate unique ID from text
|
|
119
|
+
export function generateUniqueId(text: string, prefix?: string): string {
|
|
120
|
+
const baseId = text
|
|
121
|
+
.toLowerCase()
|
|
122
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
123
|
+
.replace(/^-|-$/g, '')
|
|
124
|
+
|
|
125
|
+
return prefix ? `${prefix}_${baseId}` : baseId
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Create navigation button
|
|
129
|
+
export function createNavigationButton(
|
|
130
|
+
type: 'prev' | 'next',
|
|
131
|
+
label?: string,
|
|
132
|
+
): Tag {
|
|
133
|
+
const defaultLabels = { prev: '❮', next: '❯' }
|
|
134
|
+
const ariaLabels = { prev: 'Previous', next: 'Next' }
|
|
135
|
+
|
|
136
|
+
return new Tag(
|
|
137
|
+
'button',
|
|
138
|
+
{
|
|
139
|
+
type: 'button',
|
|
140
|
+
class: type,
|
|
141
|
+
'aria-label': ariaLabels[type],
|
|
142
|
+
},
|
|
143
|
+
[label || defaultLabels[type]],
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Create tab button for navigation
|
|
148
|
+
export function createTabButton(options: {
|
|
149
|
+
id: string
|
|
150
|
+
label: string
|
|
151
|
+
controls: string
|
|
152
|
+
selected?: boolean
|
|
153
|
+
index?: number
|
|
154
|
+
}): Tag {
|
|
155
|
+
const { id, label, controls, selected = false, index = 0 } = options
|
|
156
|
+
|
|
157
|
+
return new Tag(
|
|
158
|
+
'button',
|
|
159
|
+
{
|
|
160
|
+
role: 'tab',
|
|
161
|
+
id,
|
|
162
|
+
'aria-controls': controls,
|
|
163
|
+
'aria-label': label,
|
|
164
|
+
'aria-selected': String(selected),
|
|
165
|
+
'data-index': String(index),
|
|
166
|
+
tabindex: selected ? '0' : '-1',
|
|
167
|
+
},
|
|
168
|
+
['●'],
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Create accessible heading with anchor
|
|
173
|
+
export function createAccessibleHeading(
|
|
174
|
+
level: number,
|
|
175
|
+
text: string,
|
|
176
|
+
attributes: Record<string, any> = {},
|
|
177
|
+
): Tag {
|
|
178
|
+
const slug = generateSlug(text)
|
|
179
|
+
|
|
180
|
+
return new Tag(`h${level}`, { id: slug, ...attributes }, [
|
|
181
|
+
new Tag('a', { name: slug, class: 'anchor', href: `#${slug}` }, [
|
|
182
|
+
new Tag('span', { class: 'permalink' }, ['🔗']),
|
|
183
|
+
new Tag('span', { class: 'title' }, [text]),
|
|
184
|
+
]),
|
|
185
|
+
])
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Create visually hidden heading for accessibility
|
|
189
|
+
export function createVisuallyHiddenHeading(text: string): Tag {
|
|
190
|
+
return new Tag('h2', { class: 'visually-hidden' }, [text])
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function postProcessHtml(html: string, section?: string): string {
|
|
194
|
+
// Fix internal links (.md -> .html)
|
|
195
|
+
html = html.replace(
|
|
196
|
+
/href="([^"]*\.md)"/g,
|
|
197
|
+
(_, href) => `href="${href.replace(/\.md$/, '.html')}"`,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
// Wrap API pages
|
|
201
|
+
if (section === 'api') {
|
|
202
|
+
html = `<section class="api-content">\n${html}\n</section>`
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return html
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function generateSlug(text: string): string {
|
|
209
|
+
// Decode HTML entities first
|
|
210
|
+
const decoded = text
|
|
211
|
+
.replace(/"/g, '"')
|
|
212
|
+
.replace(/'/g, "'")
|
|
213
|
+
.replace(/&/g, '&')
|
|
214
|
+
|
|
215
|
+
// Use the existing slug generator
|
|
216
|
+
return templateSlug(decoded)
|
|
217
|
+
}
|