bretzel 0.1.0a1__tar.gz
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.
- bretzel-0.1.0a1/.claude/bretzel/README.md +71 -0
- bretzel-0.1.0a1/.claude/bretzel/app-map-model.md +151 -0
- bretzel-0.1.0a1/.claude/bretzel/app-structure.md +319 -0
- bretzel-0.1.0a1/.claude/bretzel/client-reactive-surface.md +149 -0
- bretzel-0.1.0a1/.claude/bretzel/components.md +612 -0
- bretzel-0.1.0a1/.claude/bretzel/creating-a-component.md +476 -0
- bretzel-0.1.0a1/.claude/bretzel/gates.md +229 -0
- bretzel-0.1.0a1/.claude/bretzel/handlers.md +682 -0
- bretzel-0.1.0a1/.claude/bretzel/imperative-api.md +55 -0
- bretzel-0.1.0a1/.claude/bretzel/kwarg-routing.md +240 -0
- bretzel-0.1.0a1/.claude/bretzel/livrer-une-app.md +230 -0
- bretzel-0.1.0a1/.claude/bretzel/playground-pattern.md +372 -0
- bretzel-0.1.0a1/.claude/bretzel/prose-and-comments.md +243 -0
- bretzel-0.1.0a1/.claude/bretzel/render.md +436 -0
- bretzel-0.1.0a1/.claude/bretzel/runtime.md +306 -0
- bretzel-0.1.0a1/.claude/bretzel/screen-responsive-nav.md +152 -0
- bretzel-0.1.0a1/.claude/bretzel/security.md +146 -0
- bretzel-0.1.0a1/.claude/bretzel/state.md +544 -0
- bretzel-0.1.0a1/.claude/bretzel/theme.md +554 -0
- bretzel-0.1.0a1/.claude/bretzel/traps.md +193 -0
- bretzel-0.1.0a1/.claude/launch.json +13 -0
- bretzel-0.1.0a1/.github/workflows/ci.yml +57 -0
- bretzel-0.1.0a1/.github/workflows/publish.yml +53 -0
- bretzel-0.1.0a1/.gitignore +99 -0
- bretzel-0.1.0a1/.importlinter +102 -0
- bretzel-0.1.0a1/BRAND.md +62 -0
- bretzel-0.1.0a1/CHANGELOG.md +16 -0
- bretzel-0.1.0a1/CONTRIBUTING.md +38 -0
- bretzel-0.1.0a1/LICENSE +21 -0
- bretzel-0.1.0a1/PKG-INFO +196 -0
- bretzel-0.1.0a1/README.md +147 -0
- bretzel-0.1.0a1/RELEASE.md +58 -0
- bretzel-0.1.0a1/SECURITY.md +24 -0
- bretzel-0.1.0a1/assets/brand/bretzel-mark-mono.svg +8 -0
- bretzel-0.1.0a1/assets/brand/bretzel-mark.png +0 -0
- bretzel-0.1.0a1/assets/brand/bretzel-mark.svg +4 -0
- bretzel-0.1.0a1/assets/brand/bretzel-wordmark.svg +5 -0
- bretzel-0.1.0a1/bretzel/__init__.py +120 -0
- bretzel-0.1.0a1/bretzel/cli/__init__.py +5 -0
- bretzel-0.1.0a1/bretzel/cli/commands/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/cli/commands/project.py +154 -0
- bretzel-0.1.0a1/bretzel/cli/main.py +360 -0
- bretzel-0.1.0a1/bretzel/components/__init__.py +459 -0
- bretzel-0.1.0a1/bretzel/components/actions/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/actions/_wiring.py +106 -0
- bretzel-0.1.0a1/bretzel/components/actions/button/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/actions/button/button.py +224 -0
- bretzel-0.1.0a1/bretzel/components/actions/button/theme.py +123 -0
- bretzel-0.1.0a1/bretzel/components/actions/icon_button/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/actions/icon_button/icon_button.py +151 -0
- bretzel-0.1.0a1/bretzel/components/actions/icon_button/theme.py +67 -0
- bretzel-0.1.0a1/bretzel/components/actions/link/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/actions/link/link.py +118 -0
- bretzel-0.1.0a1/bretzel/components/actions/link/theme.py +66 -0
- bretzel-0.1.0a1/bretzel/components/base/__init__.py +82 -0
- bretzel-0.1.0a1/bretzel/components/base/_wiring.py +2119 -0
- bretzel-0.1.0a1/bretzel/components/base/attrs.py +327 -0
- bretzel-0.1.0a1/bretzel/components/base/binding_discipline.py +107 -0
- bretzel-0.1.0a1/bretzel/components/base/component.py +2819 -0
- bretzel-0.1.0a1/bretzel/components/base/events.py +380 -0
- bretzel-0.1.0a1/bretzel/components/base/reactive_prop.py +508 -0
- bretzel-0.1.0a1/bretzel/components/base/responsive.py +153 -0
- bretzel-0.1.0a1/bretzel/components/base/sizes.py +163 -0
- bretzel-0.1.0a1/bretzel/components/base/testing.py +122 -0
- bretzel-0.1.0a1/bretzel/components/charts/__init__.py +40 -0
- bretzel-0.1.0a1/bretzel/components/charts/_layers.py +217 -0
- bretzel-0.1.0a1/bretzel/components/charts/_svg.py +358 -0
- bretzel-0.1.0a1/bretzel/components/charts/bar_chart/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/charts/bar_chart/bar_chart.py +1193 -0
- bretzel-0.1.0a1/bretzel/components/charts/bar_chart/theme.py +77 -0
- bretzel-0.1.0a1/bretzel/components/charts/line_chart/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/charts/line_chart/line_chart.py +793 -0
- bretzel-0.1.0a1/bretzel/components/charts/line_chart/theme.py +141 -0
- bretzel-0.1.0a1/bretzel/components/charts/pie_chart/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/charts/pie_chart/pie_chart.py +339 -0
- bretzel-0.1.0a1/bretzel/components/charts/pie_chart/theme.py +62 -0
- bretzel-0.1.0a1/bretzel/components/charts/reference.py +35 -0
- bretzel-0.1.0a1/bretzel/components/charts/scatter_chart/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/charts/scatter_chart/scatter_chart.py +309 -0
- bretzel-0.1.0a1/bretzel/components/charts/scatter_chart/theme.py +82 -0
- bretzel-0.1.0a1/bretzel/components/charts/series.py +142 -0
- bretzel-0.1.0a1/bretzel/components/charts/sparkline/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/charts/sparkline/sparkline.py +263 -0
- bretzel-0.1.0a1/bretzel/components/charts/sparkline/theme.py +53 -0
- bretzel-0.1.0a1/bretzel/components/color_shapes.py +144 -0
- bretzel-0.1.0a1/bretzel/components/data/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/data/accordion/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/data/accordion/accordion.py +694 -0
- bretzel-0.1.0a1/bretzel/components/data/accordion/theme.py +113 -0
- bretzel-0.1.0a1/bretzel/components/data/datatable/__init__.py +29 -0
- bretzel-0.1.0a1/bretzel/components/data/datatable/datatable.py +1256 -0
- bretzel-0.1.0a1/bretzel/components/data/datatable/theme.py +184 -0
- bretzel-0.1.0a1/bretzel/components/data/diagram/__init__.py +12 -0
- bretzel-0.1.0a1/bretzel/components/data/diagram/diagram.py +796 -0
- bretzel-0.1.0a1/bretzel/components/data/diagram/layout.py +633 -0
- bretzel-0.1.0a1/bretzel/components/data/diagram/theme.py +180 -0
- bretzel-0.1.0a1/bretzel/components/data/table/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/data/table/table.py +594 -0
- bretzel-0.1.0a1/bretzel/components/data/table/theme.py +126 -0
- bretzel-0.1.0a1/bretzel/components/data/tree/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/data/tree/theme.py +121 -0
- bretzel-0.1.0a1/bretzel/components/data/tree/tree.py +495 -0
- bretzel-0.1.0a1/bretzel/components/feedback/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/feedback/alert/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/alert/alert.py +221 -0
- bretzel-0.1.0a1/bretzel/components/feedback/alert/theme.py +86 -0
- bretzel-0.1.0a1/bretzel/components/feedback/avatar/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/avatar/avatar.py +265 -0
- bretzel-0.1.0a1/bretzel/components/feedback/avatar/theme.py +57 -0
- bretzel-0.1.0a1/bretzel/components/feedback/badge/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/badge/badge.py +228 -0
- bretzel-0.1.0a1/bretzel/components/feedback/badge/theme.py +144 -0
- bretzel-0.1.0a1/bretzel/components/feedback/banner/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/banner/banner.py +229 -0
- bretzel-0.1.0a1/bretzel/components/feedback/banner/theme.py +78 -0
- bretzel-0.1.0a1/bretzel/components/feedback/empty_state/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/empty_state/empty_state.py +191 -0
- bretzel-0.1.0a1/bretzel/components/feedback/empty_state/theme.py +82 -0
- bretzel-0.1.0a1/bretzel/components/feedback/notification/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/feedback/notification/notification.py +236 -0
- bretzel-0.1.0a1/bretzel/components/feedback/notification/theme.py +144 -0
- bretzel-0.1.0a1/bretzel/components/feedback/progress/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/progress/progress.py +256 -0
- bretzel-0.1.0a1/bretzel/components/feedback/progress/theme.py +48 -0
- bretzel-0.1.0a1/bretzel/components/feedback/skeleton/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/feedback/skeleton/skeleton.py +89 -0
- bretzel-0.1.0a1/bretzel/components/feedback/skeleton/theme.py +34 -0
- bretzel-0.1.0a1/bretzel/components/inputs/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/inputs/_checkable.py +197 -0
- bretzel-0.1.0a1/bretzel/components/inputs/_picker.py +447 -0
- bretzel-0.1.0a1/bretzel/components/inputs/_picker_field.py +619 -0
- bretzel-0.1.0a1/bretzel/components/inputs/_wiring.py +254 -0
- bretzel-0.1.0a1/bretzel/components/inputs/calendar/__init__.py +21 -0
- bretzel-0.1.0a1/bretzel/components/inputs/calendar/calendar.py +1228 -0
- bretzel-0.1.0a1/bretzel/components/inputs/calendar/theme.py +222 -0
- bretzel-0.1.0a1/bretzel/components/inputs/checkbox/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/checkbox/checkbox.py +132 -0
- bretzel-0.1.0a1/bretzel/components/inputs/checkbox/theme.py +74 -0
- bretzel-0.1.0a1/bretzel/components/inputs/color_picker/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/inputs/color_picker/color_picker.py +403 -0
- bretzel-0.1.0a1/bretzel/components/inputs/color_picker/theme.py +127 -0
- bretzel-0.1.0a1/bretzel/components/inputs/combobox/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/combobox/combobox.py +1243 -0
- bretzel-0.1.0a1/bretzel/components/inputs/combobox/theme.py +287 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_picker/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_picker/date_picker.py +461 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_picker/theme.py +136 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_range_picker/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_range_picker/date_range_picker.py +481 -0
- bretzel-0.1.0a1/bretzel/components/inputs/date_range_picker/theme.py +143 -0
- bretzel-0.1.0a1/bretzel/components/inputs/file_upload/__init__.py +5 -0
- bretzel-0.1.0a1/bretzel/components/inputs/file_upload/file_upload.py +936 -0
- bretzel-0.1.0a1/bretzel/components/inputs/file_upload/theme.py +433 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form/form.py +104 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form/theme.py +11 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form_field/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form_field/form_field.py +300 -0
- bretzel-0.1.0a1/bretzel/components/inputs/form_field/theme.py +20 -0
- bretzel-0.1.0a1/bretzel/components/inputs/input/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/input/input.py +440 -0
- bretzel-0.1.0a1/bretzel/components/inputs/input/theme.py +159 -0
- bretzel-0.1.0a1/bretzel/components/inputs/month_picker/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/month_picker/month_picker.py +220 -0
- bretzel-0.1.0a1/bretzel/components/inputs/month_picker/theme.py +95 -0
- bretzel-0.1.0a1/bretzel/components/inputs/number_input/__init__.py +9 -0
- bretzel-0.1.0a1/bretzel/components/inputs/number_input/number_input.py +546 -0
- bretzel-0.1.0a1/bretzel/components/inputs/number_input/theme.py +84 -0
- bretzel-0.1.0a1/bretzel/components/inputs/radio/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/radio/radio.py +444 -0
- bretzel-0.1.0a1/bretzel/components/inputs/radio/theme.py +72 -0
- bretzel-0.1.0a1/bretzel/components/inputs/select/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/select/select.py +1057 -0
- bretzel-0.1.0a1/bretzel/components/inputs/select/theme.py +246 -0
- bretzel-0.1.0a1/bretzel/components/inputs/signature_pad/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/inputs/signature_pad/signature_pad.py +385 -0
- bretzel-0.1.0a1/bretzel/components/inputs/signature_pad/theme.py +88 -0
- bretzel-0.1.0a1/bretzel/components/inputs/slider/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/slider/slider.py +694 -0
- bretzel-0.1.0a1/bretzel/components/inputs/slider/theme.py +118 -0
- bretzel-0.1.0a1/bretzel/components/inputs/switch/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/switch/switch.py +106 -0
- bretzel-0.1.0a1/bretzel/components/inputs/switch/theme.py +88 -0
- bretzel-0.1.0a1/bretzel/components/inputs/textarea/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/textarea/textarea.py +168 -0
- bretzel-0.1.0a1/bretzel/components/inputs/textarea/theme.py +36 -0
- bretzel-0.1.0a1/bretzel/components/inputs/time_picker/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/time_picker/theme.py +174 -0
- bretzel-0.1.0a1/bretzel/components/inputs/time_picker/time_picker.py +639 -0
- bretzel-0.1.0a1/bretzel/components/inputs/toggle_group/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/inputs/toggle_group/theme.py +93 -0
- bretzel-0.1.0a1/bretzel/components/inputs/toggle_group/toggle_group.py +701 -0
- bretzel-0.1.0a1/bretzel/components/inputs/week_picker/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/inputs/week_picker/theme.py +95 -0
- bretzel-0.1.0a1/bretzel/components/inputs/week_picker/week_picker.py +225 -0
- bretzel-0.1.0a1/bretzel/components/layout/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/layout/card/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/layout/card/card.py +122 -0
- bretzel-0.1.0a1/bretzel/components/layout/card/theme.py +80 -0
- bretzel-0.1.0a1/bretzel/components/layout/carousel/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/layout/carousel/carousel.py +529 -0
- bretzel-0.1.0a1/bretzel/components/layout/carousel/theme.py +157 -0
- bretzel-0.1.0a1/bretzel/components/layout/container/__init__.py +8 -0
- bretzel-0.1.0a1/bretzel/components/layout/container/container.py +59 -0
- bretzel-0.1.0a1/bretzel/components/layout/container/theme.py +29 -0
- bretzel-0.1.0a1/bretzel/components/layout/draggable/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/layout/draggable/draggable.py +183 -0
- bretzel-0.1.0a1/bretzel/components/layout/draggable/theme.py +132 -0
- bretzel-0.1.0a1/bretzel/components/layout/dropzone/__init__.py +8 -0
- bretzel-0.1.0a1/bretzel/components/layout/dropzone/dropzone.py +184 -0
- bretzel-0.1.0a1/bretzel/components/layout/dropzone/move.py +79 -0
- bretzel-0.1.0a1/bretzel/components/layout/dropzone/theme.py +62 -0
- bretzel-0.1.0a1/bretzel/components/layout/flex/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/layout/flex/flex.py +332 -0
- bretzel-0.1.0a1/bretzel/components/layout/flex/theme.py +90 -0
- bretzel-0.1.0a1/bretzel/components/layout/grid/__init__.py +8 -0
- bretzel-0.1.0a1/bretzel/components/layout/grid/grid.py +176 -0
- bretzel-0.1.0a1/bretzel/components/layout/grid/theme.py +64 -0
- bretzel-0.1.0a1/bretzel/components/layout/pane/__init__.py +8 -0
- bretzel-0.1.0a1/bretzel/components/layout/pane/pane.py +100 -0
- bretzel-0.1.0a1/bretzel/components/layout/pane/theme.py +131 -0
- bretzel-0.1.0a1/bretzel/components/layout/resizable/__init__.py +19 -0
- bretzel-0.1.0a1/bretzel/components/layout/resizable/resizable.py +732 -0
- bretzel-0.1.0a1/bretzel/components/layout/resizable/theme.py +184 -0
- bretzel-0.1.0a1/bretzel/components/layout/stack/__init__.py +11 -0
- bretzel-0.1.0a1/bretzel/components/layout/stack/stack.py +83 -0
- bretzel-0.1.0a1/bretzel/components/layout/viewport/__init__.py +8 -0
- bretzel-0.1.0a1/bretzel/components/layout/viewport/theme.py +85 -0
- bretzel-0.1.0a1/bretzel/components/layout/viewport/viewport.py +93 -0
- bretzel-0.1.0a1/bretzel/components/meta/__init__.py +3 -0
- bretzel-0.1.0a1/bretzel/components/meta/fragment/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/meta/fragment/fragment.py +79 -0
- bretzel-0.1.0a1/bretzel/components/meta/interval/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/meta/interval/interval.py +59 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/__init__.py +34 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/_ref.py +34 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/drag_each.py +62 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/each.py +83 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/filter_each.py +95 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/limit_each.py +54 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/paginate_each.py +72 -0
- bretzel-0.1.0a1/bretzel/components/meta/iteration/show_more.py +68 -0
- bretzel-0.1.0a1/bretzel/components/meta/meta_tag/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/meta/meta_tag/meta_tag.py +121 -0
- bretzel-0.1.0a1/bretzel/components/meta/outlet/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/meta/outlet/outlet.py +145 -0
- bretzel-0.1.0a1/bretzel/components/meta/title/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/meta/title/title.py +93 -0
- bretzel-0.1.0a1/bretzel/components/navigation/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/navigation/_wiring.py +446 -0
- bretzel-0.1.0a1/bretzel/components/navigation/bottom_bar/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/navigation/bottom_bar/bottom_bar.py +347 -0
- bretzel-0.1.0a1/bretzel/components/navigation/bottom_bar/theme.py +234 -0
- bretzel-0.1.0a1/bretzel/components/navigation/breadcrumb/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/navigation/breadcrumb/breadcrumb.py +365 -0
- bretzel-0.1.0a1/bretzel/components/navigation/breadcrumb/theme.py +50 -0
- bretzel-0.1.0a1/bretzel/components/navigation/navbar/__init__.py +11 -0
- bretzel-0.1.0a1/bretzel/components/navigation/navbar/navbar.py +327 -0
- bretzel-0.1.0a1/bretzel/components/navigation/navbar/theme.py +147 -0
- bretzel-0.1.0a1/bretzel/components/navigation/pagination/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/navigation/pagination/pagination.py +608 -0
- bretzel-0.1.0a1/bretzel/components/navigation/pagination/theme.py +76 -0
- bretzel-0.1.0a1/bretzel/components/navigation/sidebar/__init__.py +23 -0
- bretzel-0.1.0a1/bretzel/components/navigation/sidebar/sidebar.py +1657 -0
- bretzel-0.1.0a1/bretzel/components/navigation/sidebar/theme.py +710 -0
- bretzel-0.1.0a1/bretzel/components/navigation/stepper/__init__.py +11 -0
- bretzel-0.1.0a1/bretzel/components/navigation/stepper/stepper.py +653 -0
- bretzel-0.1.0a1/bretzel/components/navigation/stepper/theme.py +188 -0
- bretzel-0.1.0a1/bretzel/components/navigation/tabs/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/navigation/tabs/tabs.py +662 -0
- bretzel-0.1.0a1/bretzel/components/navigation/tabs/theme.py +94 -0
- bretzel-0.1.0a1/bretzel/components/overlay/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/overlay/_anchored.py +181 -0
- bretzel-0.1.0a1/bretzel/components/overlay/_modal.py +226 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dialog/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dialog/dialog.py +146 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dialog/theme.py +66 -0
- bretzel-0.1.0a1/bretzel/components/overlay/drawer/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/overlay/drawer/drawer.py +135 -0
- bretzel-0.1.0a1/bretzel/components/overlay/drawer/theme.py +129 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dropdown/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dropdown/dropdown.py +123 -0
- bretzel-0.1.0a1/bretzel/components/overlay/dropdown/theme.py +103 -0
- bretzel-0.1.0a1/bretzel/components/overlay/popover/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/overlay/popover/popover.py +106 -0
- bretzel-0.1.0a1/bretzel/components/overlay/popover/theme.py +34 -0
- bretzel-0.1.0a1/bretzel/components/overlay/tooltip/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/overlay/tooltip/theme.py +94 -0
- bretzel-0.1.0a1/bretzel/components/overlay/tooltip/tooltip.py +313 -0
- bretzel-0.1.0a1/bretzel/components/primitives/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/components/primitives/audio/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/audio/audio.py +108 -0
- bretzel-0.1.0a1/bretzel/components/primitives/audio/theme.py +23 -0
- bretzel-0.1.0a1/bretzel/components/primitives/code/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/primitives/code/code.py +132 -0
- bretzel-0.1.0a1/bretzel/components/primitives/code/theme.py +29 -0
- bretzel-0.1.0a1/bretzel/components/primitives/divider/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/divider/divider.py +104 -0
- bretzel-0.1.0a1/bretzel/components/primitives/divider/theme.py +37 -0
- bretzel-0.1.0a1/bretzel/components/primitives/heading/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/heading/heading.py +95 -0
- bretzel-0.1.0a1/bretzel/components/primitives/heading/theme.py +50 -0
- bretzel-0.1.0a1/bretzel/components/primitives/html/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/html/html.py +101 -0
- bretzel-0.1.0a1/bretzel/components/primitives/html/theme.py +22 -0
- bretzel-0.1.0a1/bretzel/components/primitives/icon/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/icon/icon.py +126 -0
- bretzel-0.1.0a1/bretzel/components/primitives/icon/theme.py +41 -0
- bretzel-0.1.0a1/bretzel/components/primitives/iframe/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/iframe/iframe.py +127 -0
- bretzel-0.1.0a1/bretzel/components/primitives/iframe/theme.py +42 -0
- bretzel-0.1.0a1/bretzel/components/primitives/image/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/image/image.py +110 -0
- bretzel-0.1.0a1/bretzel/components/primitives/image/theme.py +59 -0
- bretzel-0.1.0a1/bretzel/components/primitives/markdown/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/primitives/markdown/markdown.py +222 -0
- bretzel-0.1.0a1/bretzel/components/primitives/markdown/theme.py +42 -0
- bretzel-0.1.0a1/bretzel/components/primitives/menu_item/__init__.py +10 -0
- bretzel-0.1.0a1/bretzel/components/primitives/menu_item/menu_item.py +210 -0
- bretzel-0.1.0a1/bretzel/components/primitives/spinner/__init__.py +7 -0
- bretzel-0.1.0a1/bretzel/components/primitives/spinner/spinner.py +73 -0
- bretzel-0.1.0a1/bretzel/components/primitives/spinner/theme.py +32 -0
- bretzel-0.1.0a1/bretzel/components/primitives/text/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/components/primitives/text/text.py +160 -0
- bretzel-0.1.0a1/bretzel/components/primitives/text/theme.py +58 -0
- bretzel-0.1.0a1/bretzel/components/primitives/video/__init__.py +12 -0
- bretzel-0.1.0a1/bretzel/components/primitives/video/theme.py +64 -0
- bretzel-0.1.0a1/bretzel/components/primitives/video/track.py +111 -0
- bretzel-0.1.0a1/bretzel/components/primitives/video/video.py +199 -0
- bretzel-0.1.0a1/bretzel/core/__init__.py +65 -0
- bretzel-0.1.0a1/bretzel/core/errors.py +42 -0
- bretzel-0.1.0a1/bretzel/core/escape.py +261 -0
- bretzel-0.1.0a1/bretzel/core/identity.py +109 -0
- bretzel-0.1.0a1/bretzel/core/invoke.py +120 -0
- bretzel-0.1.0a1/bretzel/core/payload.py +121 -0
- bretzel-0.1.0a1/bretzel/core/serialize.py +66 -0
- bretzel-0.1.0a1/bretzel/core/tracking.py +153 -0
- bretzel-0.1.0a1/bretzel/core/tree.py +71 -0
- bretzel-0.1.0a1/bretzel/introspect/__init__.py +332 -0
- bretzel-0.1.0a1/bretzel/introspect/_signature.py +83 -0
- bretzel-0.1.0a1/bretzel/introspect/algebra.py +203 -0
- bretzel-0.1.0a1/bretzel/introspect/capabilities.py +846 -0
- bretzel-0.1.0a1/bretzel/introspect/components.py +395 -0
- bretzel-0.1.0a1/bretzel/introspect/emit/__init__.py +6 -0
- bretzel-0.1.0a1/bretzel/introspect/emit/text.py +422 -0
- bretzel-0.1.0a1/bretzel/introspect/methods.py +125 -0
- bretzel-0.1.0a1/bretzel/introspect/model.py +295 -0
- bretzel-0.1.0a1/bretzel/introspect/modules.py +651 -0
- bretzel-0.1.0a1/bretzel/introspect/package_tree.py +332 -0
- bretzel-0.1.0a1/bretzel/introspect/packages.py +167 -0
- bretzel-0.1.0a1/bretzel/introspect/routing.py +73 -0
- bretzel-0.1.0a1/bretzel/introspect/state.py +123 -0
- bretzel-0.1.0a1/bretzel/introspect/symbols.py +213 -0
- bretzel-0.1.0a1/bretzel/introspect/theme_sheet.py +160 -0
- bretzel-0.1.0a1/bretzel/lint/__init__.py +124 -0
- bretzel-0.1.0a1/bretzel/lint/corpus.py +160 -0
- bretzel-0.1.0a1/bretzel/lint/deep.py +140 -0
- bretzel-0.1.0a1/bretzel/lint/report.py +65 -0
- bretzel-0.1.0a1/bretzel/lint/rules/__init__.py +91 -0
- bretzel-0.1.0a1/bretzel/lint/rules/_theme_calls.py +97 -0
- bretzel-0.1.0a1/bretzel/lint/rules/handlers.py +63 -0
- bretzel-0.1.0a1/bretzel/lint/rules/injection.py +81 -0
- bretzel-0.1.0a1/bretzel/lint/rules/kwargs.py +150 -0
- bretzel-0.1.0a1/bretzel/lint/rules/lifespan.py +138 -0
- bretzel-0.1.0a1/bretzel/lint/rules/loop_state.py +151 -0
- bretzel-0.1.0a1/bretzel/lint/rules/nested_link.py +126 -0
- bretzel-0.1.0a1/bretzel/lint/rules/nested_page.py +165 -0
- bretzel-0.1.0a1/bretzel/lint/rules/partial_sizes.py +268 -0
- bretzel-0.1.0a1/bretzel/lint/rules/provenance.py +239 -0
- bretzel-0.1.0a1/bretzel/lint/rules/shape.py +167 -0
- bretzel-0.1.0a1/bretzel/lint/rules/shared_counter.py +232 -0
- bretzel-0.1.0a1/bretzel/lint/rules/sizes.py +238 -0
- bretzel-0.1.0a1/bretzel/lint/rules/specificity.py +330 -0
- bretzel-0.1.0a1/bretzel/lint/rules/tailwind.py +119 -0
- bretzel-0.1.0a1/bretzel/lint/rules/theme.py +163 -0
- bretzel-0.1.0a1/bretzel/lint/rules/transport.py +75 -0
- bretzel-0.1.0a1/bretzel/lint/rules/variant.py +270 -0
- bretzel-0.1.0a1/bretzel/lint/rules/zone_deps.py +192 -0
- bretzel-0.1.0a1/bretzel/probe/__init__.py +78 -0
- bretzel-0.1.0a1/bretzel/probe/_browser.py +119 -0
- bretzel-0.1.0a1/bretzel/probe/_probe.py +301 -0
- bretzel-0.1.0a1/bretzel/probe/_server.py +161 -0
- bretzel-0.1.0a1/bretzel/probe/_settle.py +97 -0
- bretzel-0.1.0a1/bretzel/probe/_sweep.py +248 -0
- bretzel-0.1.0a1/bretzel/probe/_window.py +353 -0
- bretzel-0.1.0a1/bretzel/render/__init__.py +140 -0
- bretzel-0.1.0a1/bretzel/render/context.py +450 -0
- bretzel-0.1.0a1/bretzel/render/decorators/__init__.py +34 -0
- bretzel-0.1.0a1/bretzel/render/decorators/download.py +140 -0
- bretzel-0.1.0a1/bretzel/render/decorators/error.py +82 -0
- bretzel-0.1.0a1/bretzel/render/decorators/layout.py +78 -0
- bretzel-0.1.0a1/bretzel/render/decorators/page.py +114 -0
- bretzel-0.1.0a1/bretzel/render/decorators/refreshable.py +746 -0
- bretzel-0.1.0a1/bretzel/render/fusion.py +147 -0
- bretzel-0.1.0a1/bretzel/render/iteration.py +149 -0
- bretzel-0.1.0a1/bretzel/render/lang.py +386 -0
- bretzel-0.1.0a1/bretzel/render/partials.py +583 -0
- bretzel-0.1.0a1/bretzel/render/pipeline.py +737 -0
- bretzel-0.1.0a1/bretzel/render/screen.py +95 -0
- bretzel-0.1.0a1/bretzel/render/serialize.py +138 -0
- bretzel-0.1.0a1/bretzel/render/shell.py +1071 -0
- bretzel-0.1.0a1/bretzel/render/texts.py +317 -0
- bretzel-0.1.0a1/bretzel/render/types.py +75 -0
- bretzel-0.1.0a1/bretzel/render/vendor.py +410 -0
- bretzel-0.1.0a1/bretzel/runtime/__init__.py +168 -0
- bretzel-0.1.0a1/bretzel/runtime/_build.py +103 -0
- bretzel-0.1.0a1/bretzel/runtime/_minify.py +206 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/00_index.js +413 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/01_signals.js +117 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/02_directives.js +0 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/03_scope.js +268 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/04_persistence.js +98 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/05_bridge.js +537 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/06_helpers.js +527 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/06_locale.js +142 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/07_calendar.js +937 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/08_file_upload.js +422 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/09_notification.js +137 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/10_charts.js +334 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/11_number_input.js +112 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/12_slider.js +122 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/13_select.js +72 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/14_combobox.js +206 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/15_pagination.js +135 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/16_accordion.js +265 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/17_carousel.js +231 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/18_time_picker.js +158 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/19_dnd.js +692 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/20_resizable.js +391 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/21_signature_pad.js +261 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/22_verbs.js +126 -0
- bretzel-0.1.0a1/bretzel/runtime/_src/23_diagram.js +129 -0
- bretzel-0.1.0a1/bretzel/runtime/envelope.py +313 -0
- bretzel-0.1.0a1/bretzel/runtime/protocol.py +348 -0
- bretzel-0.1.0a1/bretzel/runtime/runtime.js +7644 -0
- bretzel-0.1.0a1/bretzel/runtime/runtime.min.js +0 -0
- bretzel-0.1.0a1/bretzel/runtime/verbs.py +245 -0
- bretzel-0.1.0a1/bretzel/runtime/version.py +58 -0
- bretzel-0.1.0a1/bretzel/server/__init__.py +136 -0
- bretzel-0.1.0a1/bretzel/server/_dev.py +121 -0
- bretzel-0.1.0a1/bretzel/server/app.py +727 -0
- bretzel-0.1.0a1/bretzel/server/auth.py +520 -0
- bretzel-0.1.0a1/bretzel/server/config.py +462 -0
- bretzel-0.1.0a1/bretzel/server/crypto.py +68 -0
- bretzel-0.1.0a1/bretzel/server/decorators/__init__.py +15 -0
- bretzel-0.1.0a1/bretzel/server/decorators/background.py +109 -0
- bretzel-0.1.0a1/bretzel/server/decorators/identity.py +120 -0
- bretzel-0.1.0a1/bretzel/server/decorators/lifecycle.py +32 -0
- bretzel-0.1.0a1/bretzel/server/decorators/middleware.py +38 -0
- bretzel-0.1.0a1/bretzel/server/errors.py +124 -0
- bretzel-0.1.0a1/bretzel/server/feature.py +578 -0
- bretzel-0.1.0a1/bretzel/server/handlers.py +255 -0
- bretzel-0.1.0a1/bretzel/server/idempotency.py +130 -0
- bretzel-0.1.0a1/bretzel/server/lifecycle.py +575 -0
- bretzel-0.1.0a1/bretzel/server/middleware/__init__.py +22 -0
- bretzel-0.1.0a1/bretzel/server/middleware/_state.py +40 -0
- bretzel-0.1.0a1/bretzel/server/middleware/auth.py +58 -0
- bretzel-0.1.0a1/bretzel/server/middleware/csrf.py +234 -0
- bretzel-0.1.0a1/bretzel/server/middleware/render_context.py +482 -0
- bretzel-0.1.0a1/bretzel/server/middleware/security.py +120 -0
- bretzel-0.1.0a1/bretzel/server/middleware/session.py +147 -0
- bretzel-0.1.0a1/bretzel/server/navigation.py +287 -0
- bretzel-0.1.0a1/bretzel/server/oauth.py +592 -0
- bretzel-0.1.0a1/bretzel/server/pwa.py +209 -0
- bretzel-0.1.0a1/bretzel/server/routing/__init__.py +1 -0
- bretzel-0.1.0a1/bretzel/server/routing/_csv.py +70 -0
- bretzel-0.1.0a1/bretzel/server/routing/actions.py +515 -0
- bretzel-0.1.0a1/bretzel/server/routing/datatable.py +137 -0
- bretzel-0.1.0a1/bretzel/server/routing/downloads.py +139 -0
- bretzel-0.1.0a1/bretzel/server/routing/errors.py +170 -0
- bretzel-0.1.0a1/bretzel/server/routing/manifest.py +37 -0
- bretzel-0.1.0a1/bretzel/server/routing/pages.py +128 -0
- bretzel-0.1.0a1/bretzel/server/routing/realtime.py +125 -0
- bretzel-0.1.0a1/bretzel/server/routing/sse.py +79 -0
- bretzel-0.1.0a1/bretzel/server/routing/static.py +231 -0
- bretzel-0.1.0a1/bretzel/server/security.py +247 -0
- bretzel-0.1.0a1/bretzel/server/sse.py +573 -0
- bretzel-0.1.0a1/bretzel/state/__init__.py +249 -0
- bretzel-0.1.0a1/bretzel/state/base.py +565 -0
- bretzel-0.1.0a1/bretzel/state/datatable/__init__.py +18 -0
- bretzel-0.1.0a1/bretzel/state/datatable/query.py +88 -0
- bretzel-0.1.0a1/bretzel/state/datatable/state.py +235 -0
- bretzel-0.1.0a1/bretzel/state/fields/__init__.py +19 -0
- bretzel-0.1.0a1/bretzel/state/fields/computed.py +181 -0
- bretzel-0.1.0a1/bretzel/state/fields/descriptor.py +493 -0
- bretzel-0.1.0a1/bretzel/state/fields/validator.py +141 -0
- bretzel-0.1.0a1/bretzel/state/live_connection.py +33 -0
- bretzel-0.1.0a1/bretzel/state/locking.py +213 -0
- bretzel-0.1.0a1/bretzel/state/persistence/__init__.py +24 -0
- bretzel-0.1.0a1/bretzel/state/persistence/base.py +180 -0
- bretzel-0.1.0a1/bretzel/state/persistence/client_bridge.py +55 -0
- bretzel-0.1.0a1/bretzel/state/persistence/memory.py +294 -0
- bretzel-0.1.0a1/bretzel/state/persistence/redis.py +460 -0
- bretzel-0.1.0a1/bretzel/state/registry.py +723 -0
- bretzel-0.1.0a1/bretzel/state/scopes/__init__.py +30 -0
- bretzel-0.1.0a1/bretzel/state/scopes/client.py +664 -0
- bretzel-0.1.0a1/bretzel/state/scopes/server.py +442 -0
- bretzel-0.1.0a1/bretzel/state/types.py +341 -0
- bretzel-0.1.0a1/bretzel/state/url.py +330 -0
- bretzel-0.1.0a1/bretzel/static/apple-touch-icon.png +0 -0
- bretzel-0.1.0a1/bretzel/static/favicon.svg +7 -0
- bretzel-0.1.0a1/bretzel/static/marque-mono.svg +8 -0
- bretzel-0.1.0a1/bretzel/static/marque-plat.svg +4 -0
- bretzel-0.1.0a1/bretzel/static/marque.svg +4 -0
- bretzel-0.1.0a1/bretzel/theme/__init__.py +735 -0
- bretzel-0.1.0a1/bretzel/theme/bridges.py +490 -0
- bretzel-0.1.0a1/bretzel/theme/build.py +469 -0
- bretzel-0.1.0a1/bretzel/theme/color_scheme.py +97 -0
- bretzel-0.1.0a1/bretzel/theme/compiler.py +213 -0
- bretzel-0.1.0a1/bretzel/theme/config.py +51 -0
- bretzel-0.1.0a1/bretzel/theme/css.py +527 -0
- bretzel-0.1.0a1/bretzel/theme/palette.py +573 -0
- bretzel-0.1.0a1/bretzel/theme/slots.py +200 -0
- bretzel-0.1.0a1/bretzel/theme/sources.py +191 -0
- bretzel-0.1.0a1/bretzel/theme/tailwind.py +399 -0
- bretzel-0.1.0a1/bretzel/theme/tokens.py +371 -0
- bretzel-0.1.0a1/examples/atelier/__init__.py +6 -0
- bretzel-0.1.0a1/examples/atelier/core/__init__.py +1 -0
- bretzel-0.1.0a1/examples/atelier/core/db.py +245 -0
- bretzel-0.1.0a1/examples/atelier/core/epoque.py +70 -0
- bretzel-0.1.0a1/examples/atelier/core/ingest.py +438 -0
- bretzel-0.1.0a1/examples/atelier/core/perimetre.py +208 -0
- bretzel-0.1.0a1/examples/atelier/core/phases.py +253 -0
- bretzel-0.1.0a1/examples/atelier/core/theme.py +15 -0
- bretzel-0.1.0a1/examples/atelier/features/__init__.py +1 -0
- bretzel-0.1.0a1/examples/atelier/features/outils.py +109 -0
- bretzel-0.1.0a1/examples/atelier/features/outils_data.py +134 -0
- bretzel-0.1.0a1/examples/atelier/features/phases_page.py +164 -0
- bretzel-0.1.0a1/examples/atelier/features/sessions.py +49 -0
- bretzel-0.1.0a1/examples/atelier/features/shell.py +38 -0
- bretzel-0.1.0a1/examples/atelier/features/tache_detail.py +103 -0
- bretzel-0.1.0a1/examples/atelier/features/taches.py +309 -0
- bretzel-0.1.0a1/examples/atelier/features/taches_data.py +212 -0
- bretzel-0.1.0a1/examples/atelier/main.py +95 -0
- bretzel-0.1.0a1/examples/auth/README.md +171 -0
- bretzel-0.1.0a1/examples/auth/__init__.py +0 -0
- bretzel-0.1.0a1/examples/auth/core/__init__.py +0 -0
- bretzel-0.1.0a1/examples/auth/core/domain.py +140 -0
- bretzel-0.1.0a1/examples/auth/demo.py +111 -0
- bretzel-0.1.0a1/examples/auth/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/auth/features/access.py +145 -0
- bretzel-0.1.0a1/examples/auth/features/home.py +69 -0
- bretzel-0.1.0a1/examples/auth/features/login.py +179 -0
- bretzel-0.1.0a1/examples/auth/local_idp.py +235 -0
- bretzel-0.1.0a1/examples/auth/main.py +142 -0
- bretzel-0.1.0a1/examples/chat/README.md +121 -0
- bretzel-0.1.0a1/examples/chat/__init__.py +0 -0
- bretzel-0.1.0a1/examples/chat/core/__init__.py +0 -0
- bretzel-0.1.0a1/examples/chat/core/theme.py +11 -0
- bretzel-0.1.0a1/examples/chat/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/chat/features/conversation.py +214 -0
- bretzel-0.1.0a1/examples/chat/features/generator.py +112 -0
- bretzel-0.1.0a1/examples/chat/features/logic.py +124 -0
- bretzel-0.1.0a1/examples/chat/features/shell.py +85 -0
- bretzel-0.1.0a1/examples/chat/features/state.py +98 -0
- bretzel-0.1.0a1/examples/chat/main.py +52 -0
- bretzel-0.1.0a1/examples/crm/README.md +174 -0
- bretzel-0.1.0a1/examples/crm/__init__.py +0 -0
- bretzel-0.1.0a1/examples/crm/core/__init__.py +1 -0
- bretzel-0.1.0a1/examples/crm/core/db.py +332 -0
- bretzel-0.1.0a1/examples/crm/core/domain.py +202 -0
- bretzel-0.1.0a1/examples/crm/core/security.py +72 -0
- bretzel-0.1.0a1/examples/crm/core/seed.py +319 -0
- bretzel-0.1.0a1/examples/crm/core/texts.py +80 -0
- bretzel-0.1.0a1/examples/crm/core/theme.py +12 -0
- bretzel-0.1.0a1/examples/crm/core/ui.py +31 -0
- bretzel-0.1.0a1/examples/crm/donnees-test/README.md +45 -0
- bretzel-0.1.0a1/examples/crm/donnees-test/comptes-a-corriger.csv +10 -0
- bretzel-0.1.0a1/examples/crm/donnees-test/comptes-valides.csv +11 -0
- bretzel-0.1.0a1/examples/crm/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/crm/features/access.py +175 -0
- bretzel-0.1.0a1/examples/crm/features/account_detail.py +142 -0
- bretzel-0.1.0a1/examples/crm/features/accounts.py +182 -0
- bretzel-0.1.0a1/examples/crm/features/accounts_data.py +175 -0
- bretzel-0.1.0a1/examples/crm/features/activities.py +332 -0
- bretzel-0.1.0a1/examples/crm/features/activities_data.py +133 -0
- bretzel-0.1.0a1/examples/crm/features/analyse_nav.py +35 -0
- bretzel-0.1.0a1/examples/crm/features/app_map.py +25 -0
- bretzel-0.1.0a1/examples/crm/features/auth_data.py +96 -0
- bretzel-0.1.0a1/examples/crm/features/contact_detail.py +289 -0
- bretzel-0.1.0a1/examples/crm/features/contacts.py +263 -0
- bretzel-0.1.0a1/examples/crm/features/contacts_data.py +202 -0
- bretzel-0.1.0a1/examples/crm/features/deals_data.py +264 -0
- bretzel-0.1.0a1/examples/crm/features/errors.py +34 -0
- bretzel-0.1.0a1/examples/crm/features/geo.py +63 -0
- bretzel-0.1.0a1/examples/crm/features/import_data.py +149 -0
- bretzel-0.1.0a1/examples/crm/features/import_screen.py +264 -0
- bretzel-0.1.0a1/examples/crm/features/login.py +125 -0
- bretzel-0.1.0a1/examples/crm/features/nightly_hygiene.py +56 -0
- bretzel-0.1.0a1/examples/crm/features/pipeline.py +154 -0
- bretzel-0.1.0a1/examples/crm/features/realtime.py +135 -0
- bretzel-0.1.0a1/examples/crm/features/reports.py +209 -0
- bretzel-0.1.0a1/examples/crm/features/reports_data.py +144 -0
- bretzel-0.1.0a1/examples/crm/features/search.py +145 -0
- bretzel-0.1.0a1/examples/crm/features/search_data.py +130 -0
- bretzel-0.1.0a1/examples/crm/features/settings.py +250 -0
- bretzel-0.1.0a1/examples/crm/features/shell.py +211 -0
- bretzel-0.1.0a1/examples/crm/main.py +205 -0
- bretzel-0.1.0a1/examples/crm/static/favicon.svg +17 -0
- bretzel-0.1.0a1/examples/docs/__init__.py +1 -0
- bretzel-0.1.0a1/examples/docs/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/docs/features/actions_client.py +146 -0
- bretzel-0.1.0a1/examples/docs/features/actions_server.py +180 -0
- bretzel-0.1.0a1/examples/docs/features/app_map.py +218 -0
- bretzel-0.1.0a1/examples/docs/features/auth.py +170 -0
- bretzel-0.1.0a1/examples/docs/features/browser.py +261 -0
- bretzel-0.1.0a1/examples/docs/features/cadence.py +154 -0
- bretzel-0.1.0a1/examples/docs/features/capabilities.py +172 -0
- bretzel-0.1.0a1/examples/docs/features/charts.py +174 -0
- bretzel-0.1.0a1/examples/docs/features/cheatsheet.py +130 -0
- bretzel-0.1.0a1/examples/docs/features/check.py +107 -0
- bretzel-0.1.0a1/examples/docs/features/components.py +116 -0
- bretzel-0.1.0a1/examples/docs/features/config.py +214 -0
- bretzel-0.1.0a1/examples/docs/features/describe.py +88 -0
- bretzel-0.1.0a1/examples/docs/features/drag.py +152 -0
- bretzel-0.1.0a1/examples/docs/features/errors.py +25 -0
- bretzel-0.1.0a1/examples/docs/features/forms.py +165 -0
- bretzel-0.1.0a1/examples/docs/features/home.py +99 -0
- bretzel-0.1.0a1/examples/docs/features/how.py +159 -0
- bretzel-0.1.0a1/examples/docs/features/languages.py +155 -0
- bretzel-0.1.0a1/examples/docs/features/lists.py +217 -0
- bretzel-0.1.0a1/examples/docs/features/quickstart.py +118 -0
- bretzel-0.1.0a1/examples/docs/features/reactivity_client.py +130 -0
- bretzel-0.1.0a1/examples/docs/features/reactivity_server.py +141 -0
- bretzel-0.1.0a1/examples/docs/features/runtime.py +139 -0
- bretzel-0.1.0a1/examples/docs/features/scrolling.py +145 -0
- bretzel-0.1.0a1/examples/docs/features/shell.py +193 -0
- bretzel-0.1.0a1/examples/docs/features/state_client.py +113 -0
- bretzel-0.1.0a1/examples/docs/features/state_server.py +283 -0
- bretzel-0.1.0a1/examples/docs/features/structure.py +314 -0
- bretzel-0.1.0a1/examples/docs/features/stubs.py +96 -0
- bretzel-0.1.0a1/examples/docs/features/theme.py +492 -0
- bretzel-0.1.0a1/examples/docs/features/traps.py +99 -0
- bretzel-0.1.0a1/examples/docs/features/tree.py +314 -0
- bretzel-0.1.0a1/examples/docs/lib/__init__.py +1 -0
- bretzel-0.1.0a1/examples/docs/lib/blocks.py +396 -0
- bretzel-0.1.0a1/examples/docs/lib/runtime_blocks.py +210 -0
- bretzel-0.1.0a1/examples/docs/lib/runtime_surface.py +564 -0
- bretzel-0.1.0a1/examples/docs/main.py +118 -0
- bretzel-0.1.0a1/examples/ecole/__init__.py +0 -0
- bretzel-0.1.0a1/examples/ecole/core/__init__.py +1 -0
- bretzel-0.1.0a1/examples/ecole/core/db.py +641 -0
- bretzel-0.1.0a1/examples/ecole/core/domain.py +555 -0
- bretzel-0.1.0a1/examples/ecole/core/placement.py +223 -0
- bretzel-0.1.0a1/examples/ecole/core/redaction.py +376 -0
- bretzel-0.1.0a1/examples/ecole/core/seed.py +767 -0
- bretzel-0.1.0a1/examples/ecole/core/texts.py +68 -0
- bretzel-0.1.0a1/examples/ecole/core/theme.py +135 -0
- bretzel-0.1.0a1/examples/ecole/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/ecole/features/accueil.py +117 -0
- bretzel-0.1.0a1/examples/ecole/features/annees.py +231 -0
- bretzel-0.1.0a1/examples/ecole/features/appreciations.py +356 -0
- bretzel-0.1.0a1/examples/ecole/features/appreciations_data.py +263 -0
- bretzel-0.1.0a1/examples/ecole/features/cahier.py +488 -0
- bretzel-0.1.0a1/examples/ecole/features/cahier_data.py +443 -0
- bretzel-0.1.0a1/examples/ecole/features/calendrier_data.py +223 -0
- bretzel-0.1.0a1/examples/ecole/features/classe.py +458 -0
- bretzel-0.1.0a1/examples/ecole/features/classes_data.py +78 -0
- bretzel-0.1.0a1/examples/ecole/features/eleve.py +270 -0
- bretzel-0.1.0a1/examples/ecole/features/eleves_data.py +308 -0
- bretzel-0.1.0a1/examples/ecole/features/emploi_du_temps.py +782 -0
- bretzel-0.1.0a1/examples/ecole/features/errors.py +35 -0
- bretzel-0.1.0a1/examples/ecole/features/evaluation.py +368 -0
- bretzel-0.1.0a1/examples/ecole/features/evaluations.py +220 -0
- bretzel-0.1.0a1/examples/ecole/features/grille_data.py +379 -0
- bretzel-0.1.0a1/examples/ecole/features/import_data.py +308 -0
- bretzel-0.1.0a1/examples/ecole/features/import_screen.py +301 -0
- bretzel-0.1.0a1/examples/ecole/features/notes_data.py +375 -0
- bretzel-0.1.0a1/examples/ecole/features/plan.py +753 -0
- bretzel-0.1.0a1/examples/ecole/features/plan_data.py +452 -0
- bretzel-0.1.0a1/examples/ecole/features/recherche.py +105 -0
- bretzel-0.1.0a1/examples/ecole/features/reglages.py +546 -0
- bretzel-0.1.0a1/examples/ecole/features/shell.py +126 -0
- bretzel-0.1.0a1/examples/ecole/features/suivi.py +353 -0
- bretzel-0.1.0a1/examples/ecole/features/suivi_data.py +272 -0
- bretzel-0.1.0a1/examples/ecole/features/vue_classe.py +79 -0
- bretzel-0.1.0a1/examples/ecole/main.py +141 -0
- bretzel-0.1.0a1/examples/kanban/__init__.py +0 -0
- bretzel-0.1.0a1/examples/kanban/core/__init__.py +0 -0
- bretzel-0.1.0a1/examples/kanban/core/theme.py +80 -0
- bretzel-0.1.0a1/examples/kanban/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/kanban/features/donnees.py +378 -0
- bretzel-0.1.0a1/examples/kanban/features/fiche.py +231 -0
- bretzel-0.1.0a1/examples/kanban/features/logic.py +444 -0
- bretzel-0.1.0a1/examples/kanban/features/shell.py +220 -0
- bretzel-0.1.0a1/examples/kanban/features/state.py +215 -0
- bretzel-0.1.0a1/examples/kanban/features/tableau.py +269 -0
- bretzel-0.1.0a1/examples/kanban/main.py +68 -0
- bretzel-0.1.0a1/examples/messagerie/__init__.py +1 -0
- bretzel-0.1.0a1/examples/messagerie/core/__init__.py +1 -0
- bretzel-0.1.0a1/examples/messagerie/core/theme.py +12 -0
- bretzel-0.1.0a1/examples/messagerie/features/__init__.py +1 -0
- bretzel-0.1.0a1/examples/messagerie/features/boite.py +516 -0
- bretzel-0.1.0a1/examples/messagerie/features/donnees.py +561 -0
- bretzel-0.1.0a1/examples/messagerie/features/logic.py +284 -0
- bretzel-0.1.0a1/examples/messagerie/features/shell.py +81 -0
- bretzel-0.1.0a1/examples/messagerie/features/state.py +125 -0
- bretzel-0.1.0a1/examples/messagerie/main.py +61 -0
- bretzel-0.1.0a1/examples/playground/__init__.py +4 -0
- bretzel-0.1.0a1/examples/playground/app/__init__.py +0 -0
- bretzel-0.1.0a1/examples/playground/app/layout.py +83 -0
- bretzel-0.1.0a1/examples/playground/app/nav.py +109 -0
- bretzel-0.1.0a1/examples/playground/app/routes.py +188 -0
- bretzel-0.1.0a1/examples/playground/features/__init__.py +0 -0
- bretzel-0.1.0a1/examples/playground/features/accordion.py +933 -0
- bretzel-0.1.0a1/examples/playground/features/alert.py +574 -0
- bretzel-0.1.0a1/examples/playground/features/app_map.py +90 -0
- bretzel-0.1.0a1/examples/playground/features/audio.py +354 -0
- bretzel-0.1.0a1/examples/playground/features/avatar.py +462 -0
- bretzel-0.1.0a1/examples/playground/features/badge.py +673 -0
- bretzel-0.1.0a1/examples/playground/features/banner.py +527 -0
- bretzel-0.1.0a1/examples/playground/features/bar_chart.py +640 -0
- bretzel-0.1.0a1/examples/playground/features/bottom_bar.py +748 -0
- bretzel-0.1.0a1/examples/playground/features/breadcrumb.py +408 -0
- bretzel-0.1.0a1/examples/playground/features/button/__init__.py +13 -0
- bretzel-0.1.0a1/examples/playground/features/button/logic.py +48 -0
- bretzel-0.1.0a1/examples/playground/features/button/state.py +96 -0
- bretzel-0.1.0a1/examples/playground/features/button/ui.py +594 -0
- bretzel-0.1.0a1/examples/playground/features/calendar.py +866 -0
- bretzel-0.1.0a1/examples/playground/features/card.py +504 -0
- bretzel-0.1.0a1/examples/playground/features/carousel.py +743 -0
- bretzel-0.1.0a1/examples/playground/features/checkbox.py +709 -0
- bretzel-0.1.0a1/examples/playground/features/code.py +382 -0
- bretzel-0.1.0a1/examples/playground/features/color_picker.py +758 -0
- bretzel-0.1.0a1/examples/playground/features/combobox.py +894 -0
- bretzel-0.1.0a1/examples/playground/features/container.py +287 -0
- bretzel-0.1.0a1/examples/playground/features/datatable.py +817 -0
- bretzel-0.1.0a1/examples/playground/features/date_picker/__init__.py +11 -0
- bretzel-0.1.0a1/examples/playground/features/date_picker/logic.py +37 -0
- bretzel-0.1.0a1/examples/playground/features/date_picker/state.py +69 -0
- bretzel-0.1.0a1/examples/playground/features/date_picker/ui.py +793 -0
- bretzel-0.1.0a1/examples/playground/features/date_range_picker/__init__.py +5 -0
- bretzel-0.1.0a1/examples/playground/features/date_range_picker/logic.py +29 -0
- bretzel-0.1.0a1/examples/playground/features/date_range_picker/state.py +63 -0
- bretzel-0.1.0a1/examples/playground/features/date_range_picker/ui.py +780 -0
- bretzel-0.1.0a1/examples/playground/features/diagram/__init__.py +11 -0
- bretzel-0.1.0a1/examples/playground/features/diagram/logic.py +50 -0
- bretzel-0.1.0a1/examples/playground/features/diagram/state.py +113 -0
- bretzel-0.1.0a1/examples/playground/features/diagram/ui.py +548 -0
- bretzel-0.1.0a1/examples/playground/features/dialog.py +905 -0
- bretzel-0.1.0a1/examples/playground/features/divider.py +378 -0
- bretzel-0.1.0a1/examples/playground/features/dnd.py +688 -0
- bretzel-0.1.0a1/examples/playground/features/drawer.py +766 -0
- bretzel-0.1.0a1/examples/playground/features/dropdown.py +784 -0
- bretzel-0.1.0a1/examples/playground/features/empty_state.py +421 -0
- bretzel-0.1.0a1/examples/playground/features/file_upload/__init__.py +5 -0
- bretzel-0.1.0a1/examples/playground/features/file_upload/logic.py +32 -0
- bretzel-0.1.0a1/examples/playground/features/file_upload/state.py +57 -0
- bretzel-0.1.0a1/examples/playground/features/file_upload/ui.py +751 -0
- bretzel-0.1.0a1/examples/playground/features/flex.py +422 -0
- bretzel-0.1.0a1/examples/playground/features/form/__init__.py +13 -0
- bretzel-0.1.0a1/examples/playground/features/form/logic.py +110 -0
- bretzel-0.1.0a1/examples/playground/features/form/state.py +201 -0
- bretzel-0.1.0a1/examples/playground/features/form/ui.py +819 -0
- bretzel-0.1.0a1/examples/playground/features/grid.py +400 -0
- bretzel-0.1.0a1/examples/playground/features/heading.py +374 -0
- bretzel-0.1.0a1/examples/playground/features/home.py +68 -0
- bretzel-0.1.0a1/examples/playground/features/html.py +453 -0
- bretzel-0.1.0a1/examples/playground/features/icon.py +412 -0
- bretzel-0.1.0a1/examples/playground/features/icon_button.py +603 -0
- bretzel-0.1.0a1/examples/playground/features/iframe.py +413 -0
- bretzel-0.1.0a1/examples/playground/features/image.py +414 -0
- bretzel-0.1.0a1/examples/playground/features/input/__init__.py +13 -0
- bretzel-0.1.0a1/examples/playground/features/input/logic.py +48 -0
- bretzel-0.1.0a1/examples/playground/features/input/state.py +120 -0
- bretzel-0.1.0a1/examples/playground/features/input/ui.py +835 -0
- bretzel-0.1.0a1/examples/playground/features/inspection.py +57 -0
- bretzel-0.1.0a1/examples/playground/features/line_chart.py +630 -0
- bretzel-0.1.0a1/examples/playground/features/link.py +406 -0
- bretzel-0.1.0a1/examples/playground/features/markdown.py +390 -0
- bretzel-0.1.0a1/examples/playground/features/meta.py +820 -0
- bretzel-0.1.0a1/examples/playground/features/month_picker.py +536 -0
- bretzel-0.1.0a1/examples/playground/features/navbar.py +387 -0
- bretzel-0.1.0a1/examples/playground/features/notification.py +404 -0
- bretzel-0.1.0a1/examples/playground/features/number_input.py +612 -0
- bretzel-0.1.0a1/examples/playground/features/pagination.py +741 -0
- bretzel-0.1.0a1/examples/playground/features/pie_chart.py +527 -0
- bretzel-0.1.0a1/examples/playground/features/popover.py +781 -0
- bretzel-0.1.0a1/examples/playground/features/progress.py +398 -0
- bretzel-0.1.0a1/examples/playground/features/radio.py +794 -0
- bretzel-0.1.0a1/examples/playground/features/resizable.py +887 -0
- bretzel-0.1.0a1/examples/playground/features/scatter_chart.py +456 -0
- bretzel-0.1.0a1/examples/playground/features/screen.py +262 -0
- bretzel-0.1.0a1/examples/playground/features/select.py +853 -0
- bretzel-0.1.0a1/examples/playground/features/sidebar/__init__.py +10 -0
- bretzel-0.1.0a1/examples/playground/features/sidebar/logic.py +54 -0
- bretzel-0.1.0a1/examples/playground/features/sidebar/state.py +78 -0
- bretzel-0.1.0a1/examples/playground/features/sidebar/ui.py +976 -0
- bretzel-0.1.0a1/examples/playground/features/signature_pad.py +639 -0
- bretzel-0.1.0a1/examples/playground/features/skeleton.py +313 -0
- bretzel-0.1.0a1/examples/playground/features/slider.py +607 -0
- bretzel-0.1.0a1/examples/playground/features/sparkline.py +418 -0
- bretzel-0.1.0a1/examples/playground/features/spinner.py +267 -0
- bretzel-0.1.0a1/examples/playground/features/stack.py +366 -0
- bretzel-0.1.0a1/examples/playground/features/stepper.py +770 -0
- bretzel-0.1.0a1/examples/playground/features/switch.py +690 -0
- bretzel-0.1.0a1/examples/playground/features/table.py +600 -0
- bretzel-0.1.0a1/examples/playground/features/tabs.py +708 -0
- bretzel-0.1.0a1/examples/playground/features/text.py +413 -0
- bretzel-0.1.0a1/examples/playground/features/textarea.py +774 -0
- bretzel-0.1.0a1/examples/playground/features/theme_studio.py +549 -0
- bretzel-0.1.0a1/examples/playground/features/time_picker.py +763 -0
- bretzel-0.1.0a1/examples/playground/features/toggle_group.py +914 -0
- bretzel-0.1.0a1/examples/playground/features/tooltip.py +488 -0
- bretzel-0.1.0a1/examples/playground/features/tree.py +592 -0
- bretzel-0.1.0a1/examples/playground/features/video.py +511 -0
- bretzel-0.1.0a1/examples/playground/features/week_picker.py +567 -0
- bretzel-0.1.0a1/examples/playground/infra/__init__.py +0 -0
- bretzel-0.1.0a1/examples/playground/infra/errors.py +22 -0
- bretzel-0.1.0a1/examples/playground/main.py +102 -0
- bretzel-0.1.0a1/examples/pomodoro/__init__.py +4 -0
- bretzel-0.1.0a1/examples/pomodoro/features/__init__.py +1 -0
- bretzel-0.1.0a1/examples/pomodoro/features/errors.py +18 -0
- bretzel-0.1.0a1/examples/pomodoro/features/shell.py +31 -0
- bretzel-0.1.0a1/examples/pomodoro/features/timer.py +173 -0
- bretzel-0.1.0a1/examples/pomodoro/main.py +26 -0
- bretzel-0.1.0a1/examples/shared/__init__.py +1 -0
- bretzel-0.1.0a1/examples/shared/app_map_view.py +558 -0
- bretzel-0.1.0a1/pyproject.toml +255 -0
- bretzel-0.1.0a1/pyrightconfig.json +14 -0
- bretzel-0.1.0a1/tests/__init__.py +0 -0
- bretzel-0.1.0a1/tests/audit/README.md +193 -0
- bretzel-0.1.0a1/tests/audit/__init__.py +36 -0
- bretzel-0.1.0a1/tests/audit/carriers.py +106 -0
- bretzel-0.1.0a1/tests/audit/checklist.py +1384 -0
- bretzel-0.1.0a1/tests/audit/driver.py +250 -0
- bretzel-0.1.0a1/tests/audit/harness.py +191 -0
- bretzel-0.1.0a1/tests/audit/interaction.py +997 -0
- bretzel-0.1.0a1/tests/audit/probe_configrequest_is_cancelable.py +99 -0
- bretzel-0.1.0a1/tests/audit/probe_nav_disabled_cursor_2026_08_13.py +208 -0
- bretzel-0.1.0a1/tests/audit/probe_socle_2026_07_29.py +298 -0
- bretzel-0.1.0a1/tests/audit/probes.py +1084 -0
- bretzel-0.1.0a1/tests/audit/test_binding_completeness.py +318 -0
- bretzel-0.1.0a1/tests/consistency/__init__.py +9 -0
- bretzel-0.1.0a1/tests/consistency/_discovery.py +683 -0
- bretzel-0.1.0a1/tests/consistency/_mutation_audit.py +413 -0
- bretzel-0.1.0a1/tests/consistency/_no_proof_debt.txt +12 -0
- bretzel-0.1.0a1/tests/consistency/_not_a_text_slot.txt +182 -0
- bretzel-0.1.0a1/tests/consistency/_not_graded.txt +52 -0
- bretzel-0.1.0a1/tests/consistency/_ruff_baseline.txt +155 -0
- bretzel-0.1.0a1/tests/consistency/test_a_bench_never_steals_a_page.py +204 -0
- bretzel-0.1.0a1/tests/consistency/test_a_bench_serves_its_own_compiler.py +125 -0
- bretzel-0.1.0a1/tests/consistency/test_a_bound_control_transmits_every_value.py +570 -0
- bretzel-0.1.0a1/tests/consistency/test_a_capability_is_anchored.py +304 -0
- bretzel-0.1.0a1/tests/consistency/test_a_changed_tag_drops_what_it_cannot_carry.py +235 -0
- bretzel-0.1.0a1/tests/consistency/test_a_client_expression_parses_as_js.py +484 -0
- bretzel-0.1.0a1/tests/consistency/test_a_clipping_root_is_documented.py +161 -0
- bretzel-0.1.0a1/tests/consistency/test_a_color_bridge_derives_everything.py +329 -0
- bretzel-0.1.0a1/tests/consistency/test_a_coloured_surface_declares_its_foreground.py +252 -0
- bretzel-0.1.0a1/tests/consistency/test_a_commit_writes_fields_not_documents.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_a_component_class_is_described_once.py +106 -0
- bretzel-0.1.0a1/tests/consistency/test_a_component_family_shares_its_render.py +224 -0
- bretzel-0.1.0a1/tests/consistency/test_a_component_page_carries_its_cards.py +319 -0
- bretzel-0.1.0a1/tests/consistency/test_a_component_page_carries_its_preview_helpers.py +123 -0
- bretzel-0.1.0a1/tests/consistency/test_a_custom_element_rehydrates_after_a_morph.py +190 -0
- bretzel-0.1.0a1/tests/consistency/test_a_declared_transition_can_animate.py +307 -0
- bretzel-0.1.0a1/tests/consistency/test_a_dev_app_vendors_itself.py +162 -0
- bretzel-0.1.0a1/tests/consistency/test_a_documented_population_is_complete.py +205 -0
- bretzel-0.1.0a1/tests/consistency/test_a_field_is_declared_once.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_a_flex_container_spaces_its_children.py +137 -0
- bretzel-0.1.0a1/tests/consistency/test_a_flex_family_declares_every_table.py +217 -0
- bretzel-0.1.0a1/tests/consistency/test_a_guard_does_not_compare_public_paths_flatly.py +155 -0
- bretzel-0.1.0a1/tests/consistency/test_a_lint_rule_states_what_it_refuses.py +98 -0
- bretzel-0.1.0a1/tests/consistency/test_a_nested_zone_declares_what_repaints_it.py +384 -0
- bretzel-0.1.0a1/tests/consistency/test_a_page_always_declares_its_icon.py +196 -0
- bretzel-0.1.0a1/tests/consistency/test_a_panel_that_holds_a_value_is_pilotable.py +157 -0
- bretzel-0.1.0a1/tests/consistency/test_a_parent_that_sorts_children_unwraps_them.py +319 -0
- bretzel-0.1.0a1/tests/consistency/test_a_picker_bakes_its_label_map_once.py +164 -0
- bretzel-0.1.0a1/tests/consistency/test_a_playground_offers_every_color.py +139 -0
- bretzel-0.1.0a1/tests/consistency/test_a_playground_page_stays_under_the_threshold.py +174 -0
- bretzel-0.1.0a1/tests/consistency/test_a_probe_can_actually_fail.py +229 -0
- bretzel-0.1.0a1/tests/consistency/test_a_probe_takes_a_free_port.py +155 -0
- bretzel-0.1.0a1/tests/consistency/test_a_prohibition_gate_is_mutation_tested.py +368 -0
- bretzel-0.1.0a1/tests/consistency/test_a_public_name_is_never_reported_missing.py +117 -0
- bretzel-0.1.0a1/tests/consistency/test_a_radius_belongs_to_a_family.py +298 -0
- bretzel-0.1.0a1/tests/consistency/test_a_reference_chapter_names_real_symbols.py +122 -0
- bretzel-0.1.0a1/tests/consistency/test_a_relocated_change_reaches_its_carrier.py +269 -0
- bretzel-0.1.0a1/tests/consistency/test_a_runtime_seeded_state_still_has_its_python_class.py +208 -0
- bretzel-0.1.0a1/tests/consistency/test_a_scope_method_reads_a_key_its_literal_declares.py +201 -0
- bretzel-0.1.0a1/tests/consistency/test_a_scrolling_container_never_centers_unsafely.py +208 -0
- bretzel-0.1.0a1/tests/consistency/test_a_sealed_prop_refuses_with_a_sentence.py +226 -0
- bretzel-0.1.0a1/tests/consistency/test_a_seed_patch_never_overwrites.py +238 -0
- bretzel-0.1.0a1/tests/consistency/test_a_sidebar_can_always_come_back.py +226 -0
- bretzel-0.1.0a1/tests/consistency/test_a_size_off_the_table_is_refused.py +244 -0
- bretzel-0.1.0a1/tests/consistency/test_a_size_step_declares_the_same_keys.py +155 -0
- bretzel-0.1.0a1/tests/consistency/test_a_state_fiche_names_its_url.py +181 -0
- bretzel-0.1.0a1/tests/consistency/test_a_sticky_bar_stays_in_the_frozen_frame.py +238 -0
- bretzel-0.1.0a1/tests/consistency/test_a_text_param_is_named_text.py +115 -0
- bretzel-0.1.0a1/tests/consistency/test_a_theme_literal_has_one_reader.py +174 -0
- bretzel-0.1.0a1/tests/consistency/test_a_url_prop_is_never_read_as_code.py +234 -0
- bretzel-0.1.0a1/tests/consistency/test_a_vendored_script_carries_its_identity.py +136 -0
- bretzel-0.1.0a1/tests/consistency/test_a_width_ceiling_is_relative_to_its_container.py +187 -0
- bretzel-0.1.0a1/tests/consistency/test_a_wired_event_is_declared.py +224 -0
- bretzel-0.1.0a1/tests/consistency/test_a_wrapped_sidebar_end_stays_pinned.py +238 -0
- bretzel-0.1.0a1/tests/consistency/test_a_year_dropdown_stays_bounded.py +171 -0
- bretzel-0.1.0a1/tests/consistency/test_a_zone_takes_no_parameter.py +252 -0
- bretzel-0.1.0a1/tests/consistency/test_action_payload.py +49 -0
- bretzel-0.1.0a1/tests/consistency/test_action_wire_attrs.py +108 -0
- bretzel-0.1.0a1/tests/consistency/test_activate_keydown_single_sourced.py +113 -0
- bretzel-0.1.0a1/tests/consistency/test_active_layer_outranks_root.py +134 -0
- bretzel-0.1.0a1/tests/consistency/test_an_app_never_reaches_inside_the_framework.py +253 -0
- bretzel-0.1.0a1/tests/consistency/test_an_audit_selector_still_matches_something.py +205 -0
- bretzel-0.1.0a1/tests/consistency/test_an_ellipsis_never_sits_on_a_padded_box.py +185 -0
- bretzel-0.1.0a1/tests/consistency/test_an_embedded_frame_names_itself.py +333 -0
- bretzel-0.1.0a1/tests/consistency/test_an_item_event_is_named_item_click.py +161 -0
- bretzel-0.1.0a1/tests/consistency/test_anchored_panels_match.py +139 -0
- bretzel-0.1.0a1/tests/consistency/test_app_code_never_runs_on_the_loop.py +249 -0
- bretzel-0.1.0a1/tests/consistency/test_attr_precedence_is_one_contract.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_audit_coverage.py +127 -0
- bretzel-0.1.0a1/tests/consistency/test_audit_selectors_still_match.py +185 -0
- bretzel-0.1.0a1/tests/consistency/test_bindable_rule_is_single_sourced.py +104 -0
- bretzel-0.1.0a1/tests/consistency/test_bindable_surface.py +280 -0
- bretzel-0.1.0a1/tests/consistency/test_binding_lands_on_carrier.py +106 -0
- bretzel-0.1.0a1/tests/consistency/test_binding_path_is_re_evaluated.py +208 -0
- bretzel-0.1.0a1/tests/consistency/test_bool_attr_is_single_sourced.py +199 -0
- bretzel-0.1.0a1/tests/consistency/test_bridge_error_kinds_are_emitted.py +267 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_class_never_repeats_static_tokens.py +295 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_data_carries_data_not_code.py +157 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_data_literal_is_well_formed.py +381 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_globals_emitted_by_python_exist_in_js.py +209 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_on_has_no_modifiers.py +141 -0
- bretzel-0.1.0a1/tests/consistency/test_bz_on_uses_dollar_event.py +172 -0
- bretzel-0.1.0a1/tests/consistency/test_cited_symbols_resolve.py +410 -0
- bretzel-0.1.0a1/tests/consistency/test_client_expr_heuristic_holds.py +148 -0
- bretzel-0.1.0a1/tests/consistency/test_client_expression_atomic.py +221 -0
- bretzel-0.1.0a1/tests/consistency/test_client_path_single_source.py +125 -0
- bretzel-0.1.0a1/tests/consistency/test_client_state_transport_config.py +394 -0
- bretzel-0.1.0a1/tests/consistency/test_client_store_travels_as_json.py +135 -0
- bretzel-0.1.0a1/tests/consistency/test_collection_owner_decides_the_api.py +311 -0
- bretzel-0.1.0a1/tests/consistency/test_color_vocabulary_is_closed.py +241 -0
- bretzel-0.1.0a1/tests/consistency/test_color_wiring.py +75 -0
- bretzel-0.1.0a1/tests/consistency/test_component_contracts.py +182 -0
- bretzel-0.1.0a1/tests/consistency/test_components_emit_only_runtime_directives.py +274 -0
- bretzel-0.1.0a1/tests/consistency/test_config_axes_are_independent.py +139 -0
- bretzel-0.1.0a1/tests/consistency/test_control_height_ladder.py +89 -0
- bretzel-0.1.0a1/tests/consistency/test_cookie_secure_follows_transport.py +147 -0
- bretzel-0.1.0a1/tests/consistency/test_crm_owned_reads_declare_their_scope.py +354 -0
- bretzel-0.1.0a1/tests/consistency/test_css_selectors_match_the_catalogue.py +144 -0
- bretzel-0.1.0a1/tests/consistency/test_current_path_scope_has_one_author.py +80 -0
- bretzel-0.1.0a1/tests/consistency/test_declared_event_is_reachable.py +190 -0
- bretzel-0.1.0a1/tests/consistency/test_deep_lint_sees_the_drift.py +114 -0
- bretzel-0.1.0a1/tests/consistency/test_describe_renders_every_symbol.py +71 -0
- bretzel-0.1.0a1/tests/consistency/test_directional_affordance_is_pilotable.py +168 -0
- bretzel-0.1.0a1/tests/consistency/test_disabled_affordance.py +355 -0
- bretzel-0.1.0a1/tests/consistency/test_dismiss_scope_owns_its_panel.py +95 -0
- bretzel-0.1.0a1/tests/consistency/test_docs_coverage.py +214 -0
- bretzel-0.1.0a1/tests/consistency/test_e2e_owns_its_apps.py +129 -0
- bretzel-0.1.0a1/tests/consistency/test_ecole_never_sets_a_text_size.py +182 -0
- bretzel-0.1.0a1/tests/consistency/test_emitted_classes_exist_in_source.py +407 -0
- bretzel-0.1.0a1/tests/consistency/test_escape_attr_cache_still_pays.py +130 -0
- bretzel-0.1.0a1/tests/consistency/test_escape_attr_result_is_quoted.py +241 -0
- bretzel-0.1.0a1/tests/consistency/test_every_bench_page_still_renders.py +283 -0
- bretzel-0.1.0a1/tests/consistency/test_every_component_is_unit_tested.py +123 -0
- bretzel-0.1.0a1/tests/consistency/test_every_feature_kind_is_exercised.py +123 -0
- bretzel-0.1.0a1/tests/consistency/test_every_inline_script_is_in_the_policy.py +134 -0
- bretzel-0.1.0a1/tests/consistency/test_every_package_describes_itself.py +231 -0
- bretzel-0.1.0a1/tests/consistency/test_every_public_symbol_is_describable.py +338 -0
- bretzel-0.1.0a1/tests/consistency/test_example_ports_are_unique.py +139 -0
- bretzel-0.1.0a1/tests/consistency/test_examples_have_no_private_functions.py +132 -0
- bretzel-0.1.0a1/tests/consistency/test_examples_never_speak_a_dead_engine.py +233 -0
- bretzel-0.1.0a1/tests/consistency/test_examples_pass_real_kwargs.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_fixture_apps_import.py +164 -0
- bretzel-0.1.0a1/tests/consistency/test_focus_ring_follows_its_variant.py +170 -0
- bretzel-0.1.0a1/tests/consistency/test_foreground_algebra_is_mirrored.py +133 -0
- bretzel-0.1.0a1/tests/consistency/test_framework_routes_are_classified.py +332 -0
- bretzel-0.1.0a1/tests/consistency/test_framework_words_go_through_the_table.py +438 -0
- bretzel-0.1.0a1/tests/consistency/test_funnel_index_is_complete.py +102 -0
- bretzel-0.1.0a1/tests/consistency/test_handler_helpers_have_one_home.py +189 -0
- bretzel-0.1.0a1/tests/consistency/test_hidden_carrier_skeleton_is_shared.py +197 -0
- bretzel-0.1.0a1/tests/consistency/test_hover_only_controls_reachable.py +110 -0
- bretzel-0.1.0a1/tests/consistency/test_icon_follows_its_label.py +356 -0
- bretzel-0.1.0a1/tests/consistency/test_icon_only_controls_are_named.py +303 -0
- bretzel-0.1.0a1/tests/consistency/test_identity_is_read_in_one_place.py +137 -0
- bretzel-0.1.0a1/tests/consistency/test_imperative_classvar_is_complete.py +134 -0
- bretzel-0.1.0a1/tests/consistency/test_inline_root_hugs_content.py +180 -0
- bretzel-0.1.0a1/tests/consistency/test_input_root_fills_width.py +138 -0
- bretzel-0.1.0a1/tests/consistency/test_introspect_sees_inherited_props.py +160 -0
- bretzel-0.1.0a1/tests/consistency/test_lint_baseline_on_examples.py +121 -0
- bretzel-0.1.0a1/tests/consistency/test_lint_baseline_on_tests.py +199 -0
- bretzel-0.1.0a1/tests/consistency/test_lint_derives_the_corpus_once.py +166 -0
- bretzel-0.1.0a1/tests/consistency/test_lint_rules_are_not_vacuous.py +977 -0
- bretzel-0.1.0a1/tests/consistency/test_list_presentations_restructure.py +154 -0
- bretzel-0.1.0a1/tests/consistency/test_measured_deps_are_declared.py +160 -0
- bretzel-0.1.0a1/tests/consistency/test_mode_does_not_change_rendering.py +119 -0
- bretzel-0.1.0a1/tests/consistency/test_module_surfaces_are_classified.py +146 -0
- bretzel-0.1.0a1/tests/consistency/test_no_alpine_dialect_survives.py +98 -0
- bretzel-0.1.0a1/tests/consistency/test_no_alpine_vocabulary_in_prose.py +147 -0
- bretzel-0.1.0a1/tests/consistency/test_no_bucket_accepts_the_undeclared.py +130 -0
- bretzel-0.1.0a1/tests/consistency/test_no_build_token_survives_in_the_bundle.py +135 -0
- bretzel-0.1.0a1/tests/consistency/test_no_classvar_restates_the_default.py +80 -0
- bretzel-0.1.0a1/tests/consistency/test_no_colour_class_is_assembled_by_hand.py +161 -0
- bretzel-0.1.0a1/tests/consistency/test_no_component_emits_an_empty_resource_url.py +183 -0
- bretzel-0.1.0a1/tests/consistency/test_no_gate_swallows_a_component.py +318 -0
- bretzel-0.1.0a1/tests/consistency/test_no_gate_swallows_a_file.py +214 -0
- bretzel-0.1.0a1/tests/consistency/test_no_import_clause_repeats_a_name.py +154 -0
- bretzel-0.1.0a1/tests/consistency/test_no_manual_user_class_append.py +205 -0
- bretzel-0.1.0a1/tests/consistency/test_no_phantom_app_attribute.py +244 -0
- bretzel-0.1.0a1/tests/consistency/test_no_route_is_served_twice.py +272 -0
- bretzel-0.1.0a1/tests/consistency/test_no_same_specificity_conflict.py +274 -0
- bretzel-0.1.0a1/tests/consistency/test_no_state_is_built_through_the_metaclass.py +172 -0
- bretzel-0.1.0a1/tests/consistency/test_no_two_pages_share_a_scope.py +188 -0
- bretzel-0.1.0a1/tests/consistency/test_no_universal_kwarg_shadowing.py +84 -0
- bretzel-0.1.0a1/tests/consistency/test_none_kwarg_keeps_default.py +103 -0
- bretzel-0.1.0a1/tests/consistency/test_numeric_primitive_single_source.py +74 -0
- bretzel-0.1.0a1/tests/consistency/test_observed_value_writes_are_commits.py +165 -0
- bretzel-0.1.0a1/tests/consistency/test_one_name_one_object.py +137 -0
- bretzel-0.1.0a1/tests/consistency/test_one_zone_per_table.py +117 -0
- bretzel-0.1.0a1/tests/consistency/test_overlay_closed_before_paint.py +96 -0
- bretzel-0.1.0a1/tests/consistency/test_pagination_emits_no_dead_slot.py +159 -0
- bretzel-0.1.0a1/tests/consistency/test_palette_color_is_prefixed.py +129 -0
- bretzel-0.1.0a1/tests/consistency/test_palette_distinctness.py +84 -0
- bretzel-0.1.0a1/tests/consistency/test_panel_calendar_id_is_page_unique.py +107 -0
- bretzel-0.1.0a1/tests/consistency/test_physical_direction_debt_only_shrinks.py +259 -0
- bretzel-0.1.0a1/tests/consistency/test_picked_is_not_colour_only.py +137 -0
- bretzel-0.1.0a1/tests/consistency/test_picker_opens_on_its_value.py +117 -0
- bretzel-0.1.0a1/tests/consistency/test_playground_cards_follow_the_sequence.py +166 -0
- bretzel-0.1.0a1/tests/consistency/test_playground_demos_the_api.py +340 -0
- bretzel-0.1.0a1/tests/consistency/test_playground_pages_are_reachable.py +124 -0
- bretzel-0.1.0a1/tests/consistency/test_probe_benches_still_import.py +245 -0
- bretzel-0.1.0a1/tests/consistency/test_probe_boilerplate_only_shrinks.py +197 -0
- bretzel-0.1.0a1/tests/consistency/test_probes_call_the_live_api.py +179 -0
- bretzel-0.1.0a1/tests/consistency/test_probes_still_resolve.py +165 -0
- bretzel-0.1.0a1/tests/consistency/test_prohibition_gates_declare_a_floor.py +265 -0
- bretzel-0.1.0a1/tests/consistency/test_prop_class_families_are_derived.py +211 -0
- bretzel-0.1.0a1/tests/consistency/test_prose_matches_its_own_classvar.py +229 -0
- bretzel-0.1.0a1/tests/consistency/test_public_surface_is_classified.py +186 -0
- bretzel-0.1.0a1/tests/consistency/test_python_js_mirror.py +84 -0
- bretzel-0.1.0a1/tests/consistency/test_rail_tip_looks_like_a_tooltip.py +208 -0
- bretzel-0.1.0a1/tests/consistency/test_raw_htmx_stays_in_the_allowlist.py +217 -0
- bretzel-0.1.0a1/tests/consistency/test_reactive_aria_is_stringified.py +146 -0
- bretzel-0.1.0a1/tests/consistency/test_reactive_classes_universal.py +109 -0
- bretzel-0.1.0a1/tests/consistency/test_reactive_disabled_lands_somewhere.py +182 -0
- bretzel-0.1.0a1/tests/consistency/test_reactive_prop_round_trips.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_render_hatch_universal.py +371 -0
- bretzel-0.1.0a1/tests/consistency/test_render_is_universals_wrapped.py +76 -0
- bretzel-0.1.0a1/tests/consistency/test_render_never_orphans.py +180 -0
- bretzel-0.1.0a1/tests/consistency/test_reserved_kwargs_match_the_socle.py +87 -0
- bretzel-0.1.0a1/tests/consistency/test_responsive_classes_are_safelisted.py +454 -0
- bretzel-0.1.0a1/tests/consistency/test_ring_offset_matches_its_surface.py +167 -0
- bretzel-0.1.0a1/tests/consistency/test_root_slot_override_universal.py +267 -0
- bretzel-0.1.0a1/tests/consistency/test_ruff_baseline_on_the_package.py +248 -0
- bretzel-0.1.0a1/tests/consistency/test_runtime_bundle_is_fresh.py +83 -0
- bretzel-0.1.0a1/tests/consistency/test_runtime_post_carries_csrf.py +85 -0
- bretzel-0.1.0a1/tests/consistency/test_scope_keys_match_emission.py +166 -0
- bretzel-0.1.0a1/tests/consistency/test_scope_literal_debt_only_shrinks.py +204 -0
- bretzel-0.1.0a1/tests/consistency/test_scoped_events_mirror_python.py +124 -0
- bretzel-0.1.0a1/tests/consistency/test_screen_sync_guard_is_consumed.py +250 -0
- bretzel-0.1.0a1/tests/consistency/test_server_action_routing_is_shared.py +153 -0
- bretzel-0.1.0a1/tests/consistency/test_server_backed_single_dialect.py +185 -0
- bretzel-0.1.0a1/tests/consistency/test_server_config_is_resyncable.py +377 -0
- bretzel-0.1.0a1/tests/consistency/test_server_state_seed_determinism.py +173 -0
- bretzel-0.1.0a1/tests/consistency/test_server_sync_completeness.py +243 -0
- bretzel-0.1.0a1/tests/consistency/test_serversync_gating.py +130 -0
- bretzel-0.1.0a1/tests/consistency/test_serversync_key.py +93 -0
- bretzel-0.1.0a1/tests/consistency/test_single_bretzel_error.py +60 -0
- bretzel-0.1.0a1/tests/consistency/test_size_enum_is_complete.py +154 -0
- bretzel-0.1.0a1/tests/consistency/test_size_reaches_slots.py +725 -0
- bretzel-0.1.0a1/tests/consistency/test_sizes_are_distinct.py +256 -0
- bretzel-0.1.0a1/tests/consistency/test_slot_adoption.py +111 -0
- bretzel-0.1.0a1/tests/consistency/test_slot_never_orphans.py +181 -0
- bretzel-0.1.0a1/tests/consistency/test_text_slot_contract_universal.py +445 -0
- bretzel-0.1.0a1/tests/consistency/test_the_choke_point_only_shrinks.py +260 -0
- bretzel-0.1.0a1/tests/consistency/test_the_color_bridge_memo_still_pays.py +202 -0
- bretzel-0.1.0a1/tests/consistency/test_the_colour_placeholders_only_shrink.py +177 -0
- bretzel-0.1.0a1/tests/consistency/test_the_colour_steps_stay_readable.py +337 -0
- bretzel-0.1.0a1/tests/consistency/test_the_css_cache_holds_more_than_one_theme.py +391 -0
- bretzel-0.1.0a1/tests/consistency/test_the_icon_hosts_are_in_the_policy.py +110 -0
- bretzel-0.1.0a1/tests/consistency/test_the_isolated_rig_emits_what_an_app_emits.py +183 -0
- bretzel-0.1.0a1/tests/consistency/test_the_prod_css_declares_its_scan_roots.py +279 -0
- bretzel-0.1.0a1/tests/consistency/test_the_scale_is_never_recopied_in_css.py +200 -0
- bretzel-0.1.0a1/tests/consistency/test_the_studio_exports_every_knob.py +283 -0
- bretzel-0.1.0a1/tests/consistency/test_the_theme_flip_and_the_paint_share_one_resolution.py +223 -0
- bretzel-0.1.0a1/tests/consistency/test_the_theme_sheet_answers_the_question.py +119 -0
- bretzel-0.1.0a1/tests/consistency/test_theme_declaration_reaches_the_sheet.py +283 -0
- bretzel-0.1.0a1/tests/consistency/test_theme_docstring_lists_real_slots.py +154 -0
- bretzel-0.1.0a1/tests/consistency/test_theme_override_merge.py +98 -0
- bretzel-0.1.0a1/tests/consistency/test_theme_reads_are_resolved.py +135 -0
- bretzel-0.1.0a1/tests/consistency/test_theme_refuses_unknown_keys.py +188 -0
- bretzel-0.1.0a1/tests/consistency/test_themes_use_semantic_colours.py +154 -0
- bretzel-0.1.0a1/tests/consistency/test_tooltip_wrapper_keeps_its_trigger_width.py +263 -0
- bretzel-0.1.0a1/tests/consistency/test_trigger_modifiers_survive.py +168 -0
- bretzel-0.1.0a1/tests/consistency/test_truncate_needs_width.py +136 -0
- bretzel-0.1.0a1/tests/consistency/test_two_way_props.py +175 -0
- bretzel-0.1.0a1/tests/consistency/test_ui_html_call_sites_are_listed.py +182 -0
- bretzel-0.1.0a1/tests/consistency/test_user_classes_win_over_theme.py +148 -0
- bretzel-0.1.0a1/tests/consistency/test_v4_dropped_defaults_are_restored.py +164 -0
- bretzel-0.1.0a1/tests/consistency/test_vendored_scripts_stay_pinned.py +128 -0
- bretzel-0.1.0a1/tests/consistency/test_wire_id.py +59 -0
- bretzel-0.1.0a1/tests/consistency/test_zone_box_is_transparent.py +118 -0
- bretzel-0.1.0a1/tests/e2e/__init__.py +13 -0
- bretzel-0.1.0a1/tests/e2e/apps/__init__.py +4 -0
- bretzel-0.1.0a1/tests/e2e/apps/board_app.py +135 -0
- bretzel-0.1.0a1/tests/e2e/apps/counter_app.py +258 -0
- bretzel-0.1.0a1/tests/e2e/apps/todo_app.py +187 -0
- bretzel-0.1.0a1/tests/e2e/conftest.py +199 -0
- bretzel-0.1.0a1/tests/e2e/test_counter.py +392 -0
- bretzel-0.1.0a1/tests/e2e/test_dropdown_action.py +138 -0
- bretzel-0.1.0a1/tests/e2e/test_todo.py +361 -0
- bretzel-0.1.0a1/tests/fixtures/__init__.py +0 -0
- bretzel-0.1.0a1/tests/integration/__init__.py +0 -0
- bretzel-0.1.0a1/tests/integration/components/test_datatable_export.py +279 -0
- bretzel-0.1.0a1/tests/integration/components/test_datatable_roundtrip.py +298 -0
- bretzel-0.1.0a1/tests/integration/components/test_datatable_toolbar_is_preserved.py +513 -0
- bretzel-0.1.0a1/tests/integration/components/test_two_datatables_do_not_share_identity.py +230 -0
- bretzel-0.1.0a1/tests/integration/routing/__init__.py +0 -0
- bretzel-0.1.0a1/tests/integration/routing/test_errors.py +211 -0
- bretzel-0.1.0a1/tests/integration/server/__init__.py +0 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_broken_zone_does_not_sink_the_response.py +215 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_drain_renders_only_live_zones.py +189 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_link_can_name_the_outlet_it_replaces.py +118 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_lock_serialises_a_read_modify_write.py +167 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_login_door_opens_a_session.py +295 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_middleware_reads_the_signed_in_user.py +183 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_request_body_is_bounded.py +254 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_session_cookie_is_written_once.py +141 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_tab_does_not_rebroadcast_to_itself.py +139 -0
- bretzel-0.1.0a1/tests/integration/server/test_a_view_survives_its_url.py +554 -0
- bretzel-0.1.0a1/tests/integration/server/test_action_roundtrip.py +499 -0
- bretzel-0.1.0a1/tests/integration/server/test_an_async_only_backend_still_hydrates.py +288 -0
- bretzel-0.1.0a1/tests/integration/server/test_an_unchanged_zone_is_not_shipped.py +178 -0
- bretzel-0.1.0a1/tests/integration/server/test_auth_required_answers_401.py +122 -0
- bretzel-0.1.0a1/tests/integration/server/test_background.py +51 -0
- bretzel-0.1.0a1/tests/integration/server/test_blocking_app_code_frees_the_loop.py +241 -0
- bretzel-0.1.0a1/tests/integration/server/test_compression.py +177 -0
- bretzel-0.1.0a1/tests/integration/server/test_dev_watcher.py +125 -0
- bretzel-0.1.0a1/tests/integration/server/test_middleware_redirect.py +185 -0
- bretzel-0.1.0a1/tests/integration/server/test_page_identity_travels.py +153 -0
- bretzel-0.1.0a1/tests/integration/server/test_realtime.py +311 -0
- bretzel-0.1.0a1/tests/integration/server/test_redirect_header.py +150 -0
- bretzel-0.1.0a1/tests/integration/server/test_redis_broker.py +163 -0
- bretzel-0.1.0a1/tests/integration/server/test_redis_merges_instead_of_overwriting.py +112 -0
- bretzel-0.1.0a1/tests/integration/server/test_screen_responsive.py +85 -0
- bretzel-0.1.0a1/tests/integration/server/test_security_headers.py +154 -0
- bretzel-0.1.0a1/tests/integration/server/test_smoke.py +239 -0
- bretzel-0.1.0a1/tests/integration/server/test_user_middleware_actually_runs.py +142 -0
- bretzel-0.1.0a1/tests/integration/test_a_nested_zone_ships_once.py +359 -0
- bretzel-0.1.0a1/tests/integration/test_a_third_party_component_can_be_themed.py +244 -0
- bretzel-0.1.0a1/tests/integration/test_a_zone_broadcasts_only_what_it_declares.py +223 -0
- bretzel-0.1.0a1/tests/integration/test_an_async_zone_renders_on_both_paths.py +220 -0
- bretzel-0.1.0a1/tests/integration/test_example_pages_render.py +218 -0
- bretzel-0.1.0a1/tests/integration/test_feature_include.py +148 -0
- bretzel-0.1.0a1/tests/integration/test_partial_nav_keeps_identity.py +101 -0
- bretzel-0.1.0a1/tests/integration/test_the_app_language_reaches_the_document.py +118 -0
- bretzel-0.1.0a1/tests/integration/test_the_language_is_resolved_per_request.py +164 -0
- bretzel-0.1.0a1/tests/probes/README.md +139 -0
- bretzel-0.1.0a1/tests/probes/_overlay.py +68 -0
- bretzel-0.1.0a1/tests/probes/_serve.py +220 -0
- bretzel-0.1.0a1/tests/probes/bench_anchored.py +59 -0
- bretzel-0.1.0a1/tests/probes/bench_anchored_floor.py +120 -0
- bretzel-0.1.0a1/tests/probes/bench_auth.py +32 -0
- bretzel-0.1.0a1/tests/probes/bench_auth_sso.py +35 -0
- bretzel-0.1.0a1/tests/probes/bench_batch1.py +70 -0
- bretzel-0.1.0a1/tests/probes/bench_batch3.py +83 -0
- bretzel-0.1.0a1/tests/probes/bench_boost.py +73 -0
- bretzel-0.1.0a1/tests/probes/bench_bottom_bar_placement.py +76 -0
- bretzel-0.1.0a1/tests/probes/bench_bzclass_nav.py +37 -0
- bretzel-0.1.0a1/tests/probes/bench_calendar.py +46 -0
- bretzel-0.1.0a1/tests/probes/bench_calendar_marks.py +79 -0
- bretzel-0.1.0a1/tests/probes/bench_calendar_width.py +71 -0
- bretzel-0.1.0a1/tests/probes/bench_card_hover.py +57 -0
- bretzel-0.1.0a1/tests/probes/bench_chart_empty.py +75 -0
- bretzel-0.1.0a1/tests/probes/bench_charts.py +77 -0
- bretzel-0.1.0a1/tests/probes/bench_clic.py +238 -0
- bretzel-0.1.0a1/tests/probes/bench_clientevent.py +65 -0
- bretzel-0.1.0a1/tests/probes/bench_combobox.py +53 -0
- bretzel-0.1.0a1/tests/probes/bench_combobox_events.py +69 -0
- bretzel-0.1.0a1/tests/probes/bench_combobox_width.py +28 -0
- bretzel-0.1.0a1/tests/probes/bench_crm_findings.py +235 -0
- bretzel-0.1.0a1/tests/probes/bench_datatable_filter.py +112 -0
- bretzel-0.1.0a1/tests/probes/bench_datatable_pager.py +155 -0
- bretzel-0.1.0a1/tests/probes/bench_diagram.py +80 -0
- bretzel-0.1.0a1/tests/probes/bench_dialog.py +53 -0
- bretzel-0.1.0a1/tests/probes/bench_drawer.py +44 -0
- bretzel-0.1.0a1/tests/probes/bench_drawer_server_close.py +280 -0
- bretzel-0.1.0a1/tests/probes/bench_file_list.py +220 -0
- bretzel-0.1.0a1/tests/probes/bench_fileupload.py +44 -0
- bretzel-0.1.0a1/tests/probes/bench_flex_grow.py +109 -0
- bretzel-0.1.0a1/tests/probes/bench_grid_min_col.py +86 -0
- bretzel-0.1.0a1/tests/probes/bench_lang.py +62 -0
- bretzel-0.1.0a1/tests/probes/bench_link.py +61 -0
- bretzel-0.1.0a1/tests/probes/bench_load_perf.py +64 -0
- bretzel-0.1.0a1/tests/probes/bench_locale.py +97 -0
- bretzel-0.1.0a1/tests/probes/bench_mobile_overflow.py +75 -0
- bretzel-0.1.0a1/tests/probes/bench_nav_progress.py +86 -0
- bretzel-0.1.0a1/tests/probes/bench_notification.py +53 -0
- bretzel-0.1.0a1/tests/probes/bench_number_input.py +58 -0
- bretzel-0.1.0a1/tests/probes/bench_number_input_filter.py +68 -0
- bretzel-0.1.0a1/tests/probes/bench_oidc_provider.py +22 -0
- bretzel-0.1.0a1/tests/probes/bench_overflow_card.py +111 -0
- bretzel-0.1.0a1/tests/probes/bench_overlay_bubble.py +116 -0
- bretzel-0.1.0a1/tests/probes/bench_pending.py +81 -0
- bretzel-0.1.0a1/tests/probes/bench_picker_size.py +65 -0
- bretzel-0.1.0a1/tests/probes/bench_responsive_props.py +65 -0
- bretzel-0.1.0a1/tests/probes/bench_select.py +52 -0
- bretzel-0.1.0a1/tests/probes/bench_select_events.py +72 -0
- bretzel-0.1.0a1/tests/probes/bench_select_position.py +66 -0
- bretzel-0.1.0a1/tests/probes/bench_server_events.py +130 -0
- bretzel-0.1.0a1/tests/probes/bench_sidebar_collapse.py +151 -0
- bretzel-0.1.0a1/tests/probes/bench_sidebar_mount.py +96 -0
- bretzel-0.1.0a1/tests/probes/bench_sidebar_trigger.py +61 -0
- bretzel-0.1.0a1/tests/probes/bench_slider.py +63 -0
- bretzel-0.1.0a1/tests/probes/bench_switch.py +47 -0
- bretzel-0.1.0a1/tests/probes/bench_switch_server.py +97 -0
- bretzel-0.1.0a1/tests/probes/bench_tabs_url.py +72 -0
- bretzel-0.1.0a1/tests/probes/bench_text_align.py +53 -0
- bretzel-0.1.0a1/tests/probes/bench_tipiso.py +48 -0
- bretzel-0.1.0a1/tests/probes/bench_toggle_resync.py +88 -0
- bretzel-0.1.0a1/tests/probes/bench_url_memory.py +72 -0
- bretzel-0.1.0a1/tests/probes/bench_value_resync.py +93 -0
- bretzel-0.1.0a1/tests/probes/probe_anchored.py +158 -0
- bretzel-0.1.0a1/tests/probes/probe_anchored_floor.py +189 -0
- bretzel-0.1.0a1/tests/probes/probe_atelier.py +184 -0
- bretzel-0.1.0a1/tests/probes/probe_auth.py +195 -0
- bretzel-0.1.0a1/tests/probes/probe_batch1.py +164 -0
- bretzel-0.1.0a1/tests/probes/probe_batch3.py +281 -0
- bretzel-0.1.0a1/tests/probes/probe_boost.py +118 -0
- bretzel-0.1.0a1/tests/probes/probe_bottom_bar_placement.py +163 -0
- bretzel-0.1.0a1/tests/probes/probe_calendar.py +155 -0
- bretzel-0.1.0a1/tests/probes/probe_calendar_marks.py +275 -0
- bretzel-0.1.0a1/tests/probes/probe_calendar_width.py +248 -0
- bretzel-0.1.0a1/tests/probes/probe_card_hover.py +136 -0
- bretzel-0.1.0a1/tests/probes/probe_chart_empty.py +192 -0
- bretzel-0.1.0a1/tests/probes/probe_charts.py +239 -0
- bretzel-0.1.0a1/tests/probes/probe_clic.py +287 -0
- bretzel-0.1.0a1/tests/probes/probe_clientevent.py +118 -0
- bretzel-0.1.0a1/tests/probes/probe_combobox.py +170 -0
- bretzel-0.1.0a1/tests/probes/probe_combobox_events.py +123 -0
- bretzel-0.1.0a1/tests/probes/probe_combobox_width.py +53 -0
- bretzel-0.1.0a1/tests/probes/probe_crm_findings.py +313 -0
- bretzel-0.1.0a1/tests/probes/probe_datatable_filter.py +630 -0
- bretzel-0.1.0a1/tests/probes/probe_datatable_pager.py +246 -0
- bretzel-0.1.0a1/tests/probes/probe_dead_transition.py +363 -0
- bretzel-0.1.0a1/tests/probes/probe_diagram.py +332 -0
- bretzel-0.1.0a1/tests/probes/probe_dialog.py +185 -0
- bretzel-0.1.0a1/tests/probes/probe_dnd.py +273 -0
- bretzel-0.1.0a1/tests/probes/probe_download.py +149 -0
- bretzel-0.1.0a1/tests/probes/probe_drawer.py +179 -0
- bretzel-0.1.0a1/tests/probes/probe_dropdown_hover.py +131 -0
- bretzel-0.1.0a1/tests/probes/probe_ecole.py +1659 -0
- bretzel-0.1.0a1/tests/probes/probe_fileupload.py +160 -0
- bretzel-0.1.0a1/tests/probes/probe_flex_grow.py +251 -0
- bretzel-0.1.0a1/tests/probes/probe_foreground_mirror.py +87 -0
- bretzel-0.1.0a1/tests/probes/probe_grid_min_col.py +233 -0
- bretzel-0.1.0a1/tests/probes/probe_hub.py +175 -0
- bretzel-0.1.0a1/tests/probes/probe_kanban.py +623 -0
- bretzel-0.1.0a1/tests/probes/probe_lang.py +169 -0
- bretzel-0.1.0a1/tests/probes/probe_link.py +160 -0
- bretzel-0.1.0a1/tests/probes/probe_load_perf.py +124 -0
- bretzel-0.1.0a1/tests/probes/probe_locale.py +224 -0
- bretzel-0.1.0a1/tests/probes/probe_messagerie.py +549 -0
- bretzel-0.1.0a1/tests/probes/probe_mobile_overflow.py +196 -0
- bretzel-0.1.0a1/tests/probes/probe_modals.py +167 -0
- bretzel-0.1.0a1/tests/probes/probe_nav_progress.py +185 -0
- bretzel-0.1.0a1/tests/probes/probe_no_third_party.py +121 -0
- bretzel-0.1.0a1/tests/probes/probe_notification.py +127 -0
- bretzel-0.1.0a1/tests/probes/probe_number_input.py +135 -0
- bretzel-0.1.0a1/tests/probes/probe_number_input_filter.py +131 -0
- bretzel-0.1.0a1/tests/probes/probe_oauth_door.py +195 -0
- bretzel-0.1.0a1/tests/probes/probe_overflow_card.py +283 -0
- bretzel-0.1.0a1/tests/probes/probe_overlay_bubble.py +190 -0
- bretzel-0.1.0a1/tests/probes/probe_overlay_dual_event.py +179 -0
- bretzel-0.1.0a1/tests/probes/probe_overlay_refresh.py +305 -0
- bretzel-0.1.0a1/tests/probes/probe_overlays.py +166 -0
- bretzel-0.1.0a1/tests/probes/probe_pending.py +190 -0
- bretzel-0.1.0a1/tests/probes/probe_picker_imperative.py +231 -0
- bretzel-0.1.0a1/tests/probes/probe_picker_size.py +167 -0
- bretzel-0.1.0a1/tests/probes/probe_pwa.py +109 -0
- bretzel-0.1.0a1/tests/probes/probe_responsive_props.py +162 -0
- bretzel-0.1.0a1/tests/probes/probe_select.py +162 -0
- bretzel-0.1.0a1/tests/probes/probe_select_events.py +129 -0
- bretzel-0.1.0a1/tests/probes/probe_select_position.py +165 -0
- bretzel-0.1.0a1/tests/probes/probe_server_events.py +153 -0
- bretzel-0.1.0a1/tests/probes/probe_shell.py +218 -0
- bretzel-0.1.0a1/tests/probes/probe_sidebar.py +313 -0
- bretzel-0.1.0a1/tests/probes/probe_sidebar_collapse.py +330 -0
- bretzel-0.1.0a1/tests/probes/probe_sidebar_footer.py +236 -0
- bretzel-0.1.0a1/tests/probes/probe_sidebar_scroll.py +171 -0
- bretzel-0.1.0a1/tests/probes/probe_sidebar_trigger.py +157 -0
- bretzel-0.1.0a1/tests/probes/probe_slider.py +133 -0
- bretzel-0.1.0a1/tests/probes/probe_slider_click.py +230 -0
- bretzel-0.1.0a1/tests/probes/probe_studio_export.py +159 -0
- bretzel-0.1.0a1/tests/probes/probe_switch.py +107 -0
- bretzel-0.1.0a1/tests/probes/probe_switch_server.py +150 -0
- bretzel-0.1.0a1/tests/probes/probe_table.py +244 -0
- bretzel-0.1.0a1/tests/probes/probe_tabs_url.py +171 -0
- bretzel-0.1.0a1/tests/probes/probe_text_align.py +141 -0
- bretzel-0.1.0a1/tests/probes/probe_theme_toggle.py +166 -0
- bretzel-0.1.0a1/tests/probes/probe_time_picker_cells.py +152 -0
- bretzel-0.1.0a1/tests/probes/probe_tipiso.py +47 -0
- bretzel-0.1.0a1/tests/probes/probe_toggle_resync.py +134 -0
- bretzel-0.1.0a1/tests/probes/probe_tooltip.py +207 -0
- bretzel-0.1.0a1/tests/probes/probe_url_memory.py +145 -0
- bretzel-0.1.0a1/tests/probes/probe_value_resync.py +136 -0
- bretzel-0.1.0a1/tests/probes/probe_verbs.py +218 -0
- bretzel-0.1.0a1/tests/probes/probe_video_tracks.py +169 -0
- bretzel-0.1.0a1/tests/probes/test_probes.py +178 -0
- bretzel-0.1.0a1/tests/runtime_js/__init__.py +0 -0
- bretzel-0.1.0a1/tests/runtime_js/conftest.py +51 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_burst_of_mutations_is_one_refetch.py +246 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_centered_pane_keeps_its_top_reachable.py +148 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_centered_stack_keeps_its_top_reachable.py +184 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_closed_overlay_is_out_of_the_tab_order.py +159 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_draggable_card_still_lets_the_finger_scroll.py +204 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_frozen_screen_scrolls_only_its_panes.py +289 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_link_button_is_a_real_link.py +189 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_page_runs_under_its_own_policy.py +183 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_partial_nav_never_clobbers_client_state.py +212 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_rail_without_a_logo_has_no_empty_link.py +200 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_refusal_that_mutates_nothing_snaps_back.py +223 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_scope_key_survives_a_child_of_the_same_name.py +142 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_scrolling_column_does_not_crush_its_items.py +160 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_sidebar_end_does_not_scroll_away.py +208 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_splitter_spaces_bounds_and_folds.py +235 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_tooltip_arrow_points_at_its_trigger.py +153 -0
- bretzel-0.1.0a1/tests/runtime_js/test_a_weekday_header_names_its_day.py +139 -0
- bretzel-0.1.0a1/tests/runtime_js/test_an_addressable_value_with_spaces_travels.py +155 -0
- bretzel-0.1.0a1/tests/runtime_js/test_an_unsigned_action_never_leaves.py +140 -0
- bretzel-0.1.0a1/tests/runtime_js/test_backdrop_never_covers_its_panel.py +226 -0
- bretzel-0.1.0a1/tests/runtime_js/test_boost_nav_does_not_share_state.py +186 -0
- bretzel-0.1.0a1/tests/runtime_js/test_boost_nav_keeps_pickers_live.py +138 -0
- bretzel-0.1.0a1/tests/runtime_js/test_bzclass_releases_on_rebind.py +162 -0
- bretzel-0.1.0a1/tests/runtime_js/test_bzclass_survives_morph.py +94 -0
- bretzel-0.1.0a1/tests/runtime_js/test_calendar_month_mode.py +174 -0
- bretzel-0.1.0a1/tests/runtime_js/test_calendar_range_pending_survives_rescan.py +215 -0
- bretzel-0.1.0a1/tests/runtime_js/test_calendar_survives_its_zone_refresh.py +195 -0
- bretzel-0.1.0a1/tests/runtime_js/test_calendar_week_mode.py +227 -0
- bretzel-0.1.0a1/tests/runtime_js/test_carousel_scope_geometry.py +361 -0
- bretzel-0.1.0a1/tests/runtime_js/test_chat_example_streams.py +149 -0
- bretzel-0.1.0a1/tests/runtime_js/test_classes_binding_applies.py +87 -0
- bretzel-0.1.0a1/tests/runtime_js/test_client_store_travels_as_json.py +99 -0
- bretzel-0.1.0a1/tests/runtime_js/test_component_audit.py +93 -0
- bretzel-0.1.0a1/tests/runtime_js/test_date_picker_disabled_binding.py +123 -0
- bretzel-0.1.0a1/tests/runtime_js/test_dnd_end_to_end.py +329 -0
- bretzel-0.1.0a1/tests/runtime_js/test_dnd_gesture.py +415 -0
- bretzel-0.1.0a1/tests/runtime_js/test_dnd_props.py +370 -0
- bretzel-0.1.0a1/tests/runtime_js/test_form_controls_share_one_height.py +349 -0
- bretzel-0.1.0a1/tests/runtime_js/test_full_height_layout_scrolls.py +95 -0
- bretzel-0.1.0a1/tests/runtime_js/test_image_box_survives_a_broken_url.py +85 -0
- bretzel-0.1.0a1/tests/runtime_js/test_inert_controls.py +162 -0
- bretzel-0.1.0a1/tests/runtime_js/test_morph_preserves_reordered_nodes.py +167 -0
- bretzel-0.1.0a1/tests/runtime_js/test_multiselect_mixin.py +135 -0
- bretzel-0.1.0a1/tests/runtime_js/test_navbar_path_resync.py +113 -0
- bretzel-0.1.0a1/tests/runtime_js/test_no_page_throws_on_load.py +287 -0
- bretzel-0.1.0a1/tests/runtime_js/test_notification_animation.py +128 -0
- bretzel-0.1.0a1/tests/runtime_js/test_redirect_actually_navigates.py +73 -0
- bretzel-0.1.0a1/tests/runtime_js/test_resizable_mirrors_python.py +134 -0
- bretzel-0.1.0a1/tests/runtime_js/test_screen_switch_costs_one_reload.py +222 -0
- bretzel-0.1.0a1/tests/runtime_js/test_send_to_server_is_honoured.py +279 -0
- bretzel-0.1.0a1/tests/runtime_js/test_shared_scope_factories.py +141 -0
- bretzel-0.1.0a1/tests/runtime_js/test_signature_pad_repaints_existing.py +145 -0
- bretzel-0.1.0a1/tests/runtime_js/test_step_disabled_paints.py +125 -0
- bretzel-0.1.0a1/tests/runtime_js/test_stepper_scope_bounds.py +172 -0
- bretzel-0.1.0a1/tests/runtime_js/test_the_bridge_declares_its_zones.py +120 -0
- bretzel-0.1.0a1/tests/runtime_js/test_the_harness_refuses_a_missed_drop.py +136 -0
- bretzel-0.1.0a1/tests/runtime_js/test_the_minified_runtime_boots.py +122 -0
- bretzel-0.1.0a1/tests/runtime_js/test_the_sidebar_can_always_be_collapsed.py +211 -0
- bretzel-0.1.0a1/tests/runtime_js/test_time_scope_parts.py +157 -0
- bretzel-0.1.0a1/tests/unit/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/cli/__init__.py +1 -0
- bretzel-0.1.0a1/tests/unit/cli/test_project.py +75 -0
- bretzel-0.1.0a1/tests/unit/components/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/actions/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/actions/button/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/actions/button/test_button.py +309 -0
- bretzel-0.1.0a1/tests/unit/components/actions/button/test_button_loading_mutex.py +72 -0
- bretzel-0.1.0a1/tests/unit/components/actions/button/test_button_reactive_label.py +110 -0
- bretzel-0.1.0a1/tests/unit/components/actions/icon_button/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/actions/icon_button/test_icon_button_reactive.py +66 -0
- bretzel-0.1.0a1/tests/unit/components/actions/link/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/actions/link/test_link_reactive.py +50 -0
- bretzel-0.1.0a1/tests/unit/components/base/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_adopt_slot.py +38 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_attrs.py +198 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_binding_discipline.py +156 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_classes_style_binding.py +74 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_component.py +548 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_compose_reactive.py +27 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_events.py +274 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_reactive_prop.py +157 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_scope_identity.py +54 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_text_slot.py +68 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_universal_modifiers.py +124 -0
- bretzel-0.1.0a1/tests/unit/components/base/test_user_classes.py +55 -0
- bretzel-0.1.0a1/tests/unit/components/charts/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_bar_chart.py +344 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_line_chart.py +346 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_pie_chart.py +184 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_scatter_chart.py +146 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_sparkline.py +98 -0
- bretzel-0.1.0a1/tests/unit/components/charts/test_svg_helpers.py +214 -0
- bretzel-0.1.0a1/tests/unit/components/data/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/data/accordion/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/data/accordion/test_accordion.py +650 -0
- bretzel-0.1.0a1/tests/unit/components/data/test_datatable.py +578 -0
- bretzel-0.1.0a1/tests/unit/components/data/test_diagram.py +215 -0
- bretzel-0.1.0a1/tests/unit/components/data/test_diagram_layout.py +297 -0
- bretzel-0.1.0a1/tests/unit/components/data/test_table.py +274 -0
- bretzel-0.1.0a1/tests/unit/components/data/tree/__init__.py +1 -0
- bretzel-0.1.0a1/tests/unit/components/data/tree/test_tree.py +236 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/alert/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/alert/test_alert.py +125 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/alert/test_alert_reactive_slots.py +60 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/avatar/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/avatar/test_avatar_reactive_slots.py +64 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/badge/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/badge/test_badge_reactive_slots.py +232 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/banner/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/banner/test_banner.py +211 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/empty_state/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/empty_state/test_empty_state.py +195 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/skeleton/test_skeleton.py +44 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/test_notification.py +151 -0
- bretzel-0.1.0a1/tests/unit/components/feedback/test_progress.py +111 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/calendar/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/calendar/test_calendar.py +560 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/calendar/test_calendar_marks.py +158 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/combobox/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/combobox/test_combobox.py +1091 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/date_picker/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/date_picker/test_date_picker.py +272 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/date_range_picker/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/date_range_picker/test_date_range_picker.py +215 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/file_upload/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/file_upload/test_file_upload.py +625 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/form/test_form.py +53 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/number_input/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/number_input/test_number_input.py +512 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/slider/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/slider/test_slider.py +547 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_binding_x_model.py +341 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_checkbox.py +143 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_color_picker.py +149 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_form_field.py +268 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_input.py +185 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_month_week_pickers.py +200 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_radio.py +336 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_select.py +852 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_signature_pad.py +212 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_switch.py +121 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_textarea.py +274 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/test_time_picker.py +289 -0
- bretzel-0.1.0a1/tests/unit/components/inputs/toggle_group/test_toggle_group.py +469 -0
- bretzel-0.1.0a1/tests/unit/components/layout/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/layout/card/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/layout/card/test_card_href.py +47 -0
- bretzel-0.1.0a1/tests/unit/components/layout/card/test_card_overflow.py +102 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_carousel.py +363 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_container.py +96 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_dnd.py +268 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_flex_grow.py +146 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_flex_refuses_a_value_off_table.py +99 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_flex_stack.py +266 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_grid.py +146 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_grid_min_col.py +116 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_resizable.py +358 -0
- bretzel-0.1.0a1/tests/unit/components/layout/test_viewport_pane.py +136 -0
- bretzel-0.1.0a1/tests/unit/components/meta/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/meta/fragment/test_fragment.py +117 -0
- bretzel-0.1.0a1/tests/unit/components/meta/meta_tag/test_meta_tag.py +126 -0
- bretzel-0.1.0a1/tests/unit/components/meta/test_filter_each.py +59 -0
- bretzel-0.1.0a1/tests/unit/components/meta/test_interval.py +44 -0
- bretzel-0.1.0a1/tests/unit/components/meta/test_limit_each.py +60 -0
- bretzel-0.1.0a1/tests/unit/components/meta/test_outlet.py +100 -0
- bretzel-0.1.0a1/tests/unit/components/meta/test_paginate_each.py +57 -0
- bretzel-0.1.0a1/tests/unit/components/meta/title/test_title.py +87 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_bottom_bar.py +286 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_breadcrumb.py +294 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_nav_item_wiring.py +252 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_navbar.py +222 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_pagination.py +399 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_sidebar.py +920 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_sidebar_trigger.py +131 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_stepper.py +315 -0
- bretzel-0.1.0a1/tests/unit/components/navigation/test_tabs.py +572 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_dialog.py +477 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_drawer.py +142 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_dropdown.py +326 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_full_width_trigger.py +100 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_popover.py +329 -0
- bretzel-0.1.0a1/tests/unit/components/overlay/test_tooltip.py +337 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/code/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/code/test_code.py +113 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/divider/test_divider.py +56 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/heading/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/heading/test_heading_reactive.py +58 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/icon/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/icon/test_icon_reactive_name.py +68 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/markdown/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/markdown/test_markdown.py +269 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_audio.py +82 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_html.py +104 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_iframe.py +125 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_image.py +154 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_spinner.py +65 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_text.py +173 -0
- bretzel-0.1.0a1/tests/unit/components/primitives/test_video.py +226 -0
- bretzel-0.1.0a1/tests/unit/components/test_imperative_classvar.py +93 -0
- bretzel-0.1.0a1/tests/unit/components/test_namespace.py +41 -0
- bretzel-0.1.0a1/tests/unit/core/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/core/test_escape.py +175 -0
- bretzel-0.1.0a1/tests/unit/core/test_identity.py +113 -0
- bretzel-0.1.0a1/tests/unit/core/test_serialize.py +160 -0
- bretzel-0.1.0a1/tests/unit/core/test_tracking.py +262 -0
- bretzel-0.1.0a1/tests/unit/core/test_tree.py +165 -0
- bretzel-0.1.0a1/tests/unit/examples/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/examples/test_atelier_epoque.py +150 -0
- bretzel-0.1.0a1/tests/unit/examples/test_atelier_perimetre.py +107 -0
- bretzel-0.1.0a1/tests/unit/examples/test_ecole_import.py +90 -0
- bretzel-0.1.0a1/tests/unit/examples/test_ecole_placement.py +171 -0
- bretzel-0.1.0a1/tests/unit/examples/test_ecole_redaction.py +194 -0
- bretzel-0.1.0a1/tests/unit/examples/test_ecole_regles_transverses.py +450 -0
- bretzel-0.1.0a1/tests/unit/probe/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/probe/test_the_sweep_sees_clipped_content.py +139 -0
- bretzel-0.1.0a1/tests/unit/render/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/render/test_context.py +225 -0
- bretzel-0.1.0a1/tests/unit/render/test_decorators.py +307 -0
- bretzel-0.1.0a1/tests/unit/render/test_fusion.py +165 -0
- bretzel-0.1.0a1/tests/unit/render/test_partials.py +281 -0
- bretzel-0.1.0a1/tests/unit/render/test_pipeline.py +681 -0
- bretzel-0.1.0a1/tests/unit/render/test_refreshable_deps.py +289 -0
- bretzel-0.1.0a1/tests/unit/render/test_screen.py +89 -0
- bretzel-0.1.0a1/tests/unit/render/test_serialize_html.py +95 -0
- bretzel-0.1.0a1/tests/unit/render/test_shell.py +495 -0
- bretzel-0.1.0a1/tests/unit/render/test_texts.py +278 -0
- bretzel-0.1.0a1/tests/unit/render/test_types.py +58 -0
- bretzel-0.1.0a1/tests/unit/runtime/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/runtime/test_build.py +187 -0
- bretzel-0.1.0a1/tests/unit/runtime/test_envelope.py +317 -0
- bretzel-0.1.0a1/tests/unit/runtime/test_protocol.py +126 -0
- bretzel-0.1.0a1/tests/unit/runtime/test_verbs.py +152 -0
- bretzel-0.1.0a1/tests/unit/server/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/server/decorators/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/server/decorators/test_background.py +77 -0
- bretzel-0.1.0a1/tests/unit/server/middleware/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/server/middleware/test_csrf.py +244 -0
- bretzel-0.1.0a1/tests/unit/server/routing/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/server/routing/test_actions_form_state.py +300 -0
- bretzel-0.1.0a1/tests/unit/server/routing/test_pages.py +82 -0
- bretzel-0.1.0a1/tests/unit/server/test_app_run.py +128 -0
- bretzel-0.1.0a1/tests/unit/server/test_auth.py +276 -0
- bretzel-0.1.0a1/tests/unit/server/test_config.py +123 -0
- bretzel-0.1.0a1/tests/unit/server/test_crypto.py +91 -0
- bretzel-0.1.0a1/tests/unit/server/test_dev.py +253 -0
- bretzel-0.1.0a1/tests/unit/server/test_downloads.py +183 -0
- bretzel-0.1.0a1/tests/unit/server/test_errors.py +119 -0
- bretzel-0.1.0a1/tests/unit/server/test_feature.py +358 -0
- bretzel-0.1.0a1/tests/unit/server/test_handlers.py +198 -0
- bretzel-0.1.0a1/tests/unit/server/test_identity_chain.py +216 -0
- bretzel-0.1.0a1/tests/unit/server/test_oauth_transport.py +93 -0
- bretzel-0.1.0a1/tests/unit/server/test_protocol_compat_gate.py +67 -0
- bretzel-0.1.0a1/tests/unit/server/test_pwa.py +141 -0
- bretzel-0.1.0a1/tests/unit/server/test_sse_broker.py +406 -0
- bretzel-0.1.0a1/tests/unit/server/test_static_dir.py +63 -0
- bretzel-0.1.0a1/tests/unit/state/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/state/fields/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/state/fields/test_computed.py +285 -0
- bretzel-0.1.0a1/tests/unit/state/fields/test_descriptor.py +445 -0
- bretzel-0.1.0a1/tests/unit/state/fields/test_validator.py +248 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/conftest.py +26 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/test_both_backends_agree.py +365 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/test_client_bridge.py +55 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/test_memory.py +263 -0
- bretzel-0.1.0a1/tests/unit/state/persistence/test_redis.py +293 -0
- bretzel-0.1.0a1/tests/unit/state/scopes/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/state/scopes/test_client.py +457 -0
- bretzel-0.1.0a1/tests/unit/state/scopes/test_server.py +157 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_backend_bounds_its_own_wait.py +225 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_business_type_survives_the_store.py +347 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_commit_keeps_a_concurrent_field.py +209 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_commit_writes_in_one_window.py +163 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_counter_counts_every_click.py +233 -0
- bretzel-0.1.0a1/tests/unit/state/test_a_state_needs_no_future_import.py +207 -0
- bretzel-0.1.0a1/tests/unit/state/test_base.py +312 -0
- bretzel-0.1.0a1/tests/unit/state/test_client_expression_refuses_mutation.py +77 -0
- bretzel-0.1.0a1/tests/unit/state/test_live_connection.py +52 -0
- bretzel-0.1.0a1/tests/unit/state/test_public_api.py +151 -0
- bretzel-0.1.0a1/tests/unit/state/test_registry.py +372 -0
- bretzel-0.1.0a1/tests/unit/state/test_snapshot_diff.py +128 -0
- bretzel-0.1.0a1/tests/unit/state/test_the_memory_store_does_not_grow_forever.py +146 -0
- bretzel-0.1.0a1/tests/unit/theme/__init__.py +0 -0
- bretzel-0.1.0a1/tests/unit/theme/test_color_scheme.py +106 -0
- bretzel-0.1.0a1/tests/unit/theme/test_compiler.py +212 -0
- bretzel-0.1.0a1/tests/unit/theme/test_css.py +176 -0
- bretzel-0.1.0a1/tests/unit/theme/test_palette.py +235 -0
- bretzel-0.1.0a1/tests/unit/theme/test_slots.py +90 -0
- bretzel-0.1.0a1/tests/unit/theme/test_tailwind.py +162 -0
- bretzel-0.1.0a1/tests/unit/theme/test_theme.py +232 -0
- bretzel-0.1.0a1/tests/unit/theme/test_tokens.py +65 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Référence Bretzel
|
|
2
|
+
|
|
3
|
+
Ce dossier explique les mécanismes et les conventions que le code seul ne rend
|
|
4
|
+
pas évidents. Il ne contient ni roadmap, ni inventaire manuel de l'API, ni état
|
|
5
|
+
de chantier.
|
|
6
|
+
|
|
7
|
+
Pour connaître la surface livrée :
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
bretzel describe
|
|
11
|
+
bretzel describe button
|
|
12
|
+
bretzel describe ClientBinding
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`describe` dérive les signatures, bindings, événements, slots, commandes
|
|
16
|
+
impératives et clés de thème depuis le code. Il remplace les anciens
|
|
17
|
+
`api-index.md` et `inventory.md`.
|
|
18
|
+
|
|
19
|
+
## Choisir le bon document
|
|
20
|
+
|
|
21
|
+
| Besoin | Référence |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Créer et livrer un composant | [`creating-a-component.md`](creating-a-component.md) |
|
|
24
|
+
| Comprendre le socle des composants | [`components.md`](components.md) |
|
|
25
|
+
| Décider si une prop est réactive côté client | [`client-reactive-surface.md`](client-reactive-surface.md) |
|
|
26
|
+
| Comprendre le routage des kwargs | [`kwarg-routing.md`](kwarg-routing.md) |
|
|
27
|
+
| Utiliser les commandes `.open()`, `.set()`… | [`imperative-api.md`](imperative-api.md) |
|
|
28
|
+
| Déclarer et persister un état | [`state.md`](state.md) |
|
|
29
|
+
| Écrire un handler | [`handlers.md`](handlers.md) |
|
|
30
|
+
| Comprendre le rendu et les refreshables | [`render.md`](render.md) |
|
|
31
|
+
| Comprendre le runtime `bz-*` | [`runtime.md`](runtime.md) |
|
|
32
|
+
| Composer ou surcharger un thème | [`theme.md`](theme.md) |
|
|
33
|
+
| Vérifier sécurité, cookies et CSP | [`security.md`](security.md) |
|
|
34
|
+
| Structurer une application | [`app-structure.md`](app-structure.md) |
|
|
35
|
+
| Livrer une application | [`livrer-une-app.md`](livrer-une-app.md) |
|
|
36
|
+
| Construire une navigation responsive | [`screen-responsive-nav.md`](screen-responsive-nav.md) |
|
|
37
|
+
| Ajouter une page au playground | [`playground-pattern.md`](playground-pattern.md) |
|
|
38
|
+
| Comprendre la carte d'application | [`app-map-model.md`](app-map-model.md) |
|
|
39
|
+
| Écrire une gate de cohérence | [`gates.md`](gates.md) |
|
|
40
|
+
| Écrire commentaires et docstrings | [`prose-and-comments.md`](prose-and-comments.md) |
|
|
41
|
+
| Retrouver un piège technique précis | [`traps.md`](traps.md) |
|
|
42
|
+
|
|
43
|
+
Le travail ouvert et les rapports vivent dans [`.claude/work/`](../work/).
|
|
44
|
+
|
|
45
|
+
## Contrats transverses
|
|
46
|
+
|
|
47
|
+
1. L'API applicative canonique est en Python. Les directives `bz-*` et les
|
|
48
|
+
attributs de transport sont produits par le framework.
|
|
49
|
+
2. Une action serveur passe par un paramètre `on_<event>` ; le framework ajoute
|
|
50
|
+
la route, la signature et les en-têtes nécessaires.
|
|
51
|
+
3. Seules les props déclarées dans `BINDABLE_PROPS` acceptent un
|
|
52
|
+
`ClientBinding`. `bretzel describe <composant>` les affiche.
|
|
53
|
+
4. Les commandes d'instance sont write-only. Pour partager ou lire une valeur,
|
|
54
|
+
utiliser un binding explicite.
|
|
55
|
+
5. Un champ de formulaire lié reçoit son `name` automatiquement.
|
|
56
|
+
6. Les modules forment un graphe d'import acyclique. Le socle ne dépend pas des
|
|
57
|
+
couches applicatives.
|
|
58
|
+
7. Les exemples montrent l'usage public et restent lisibles sans plomberie
|
|
59
|
+
interne.
|
|
60
|
+
8. Une nouvelle règle structurelle est protégée par une gate qui prouve aussi
|
|
61
|
+
qu'elle détecte le défaut visé.
|
|
62
|
+
|
|
63
|
+
## Entretien
|
|
64
|
+
|
|
65
|
+
- Changement de surface publique : mettre à jour les docstrings introspectées
|
|
66
|
+
et vérifier avec `bretzel describe`.
|
|
67
|
+
- Changement de mécanisme : mettre à jour la référence de couche concernée.
|
|
68
|
+
- Dette nouvelle : l'ajouter à `.claude/work/todo.md`, avec sa preuve.
|
|
69
|
+
- Fichier de référence ajouté ou supprimé : mettre cet index à jour.
|
|
70
|
+
- Récit daté ou correction terminée : le retirer de la référence vivante ; Git
|
|
71
|
+
conserve l'historique.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Carte d'app — le modèle v4 (ACTÉ, 2026-07-05)
|
|
2
|
+
|
|
3
|
+
> Statut : **ACTÉ** — fork socle tranché par l'utilisateur : **Option A**
|
|
4
|
+
> (groupes socle accrochés aux layouts uniquement, jamais aux pages ;
|
|
5
|
+
> le privé-à-une-page remonte au layout avec badge). Le composant
|
|
6
|
+
> ``examples/shared/app_map_view.py`` est construit sur ce modèle.
|
|
7
|
+
|
|
8
|
+
## Pourquoi une v4 — les défauts constatés (tous vérifiés sur MAD)
|
|
9
|
+
|
|
10
|
+
1. **Une ligne = deux fonctions.** `_render_node : if kids or socle →
|
|
11
|
+
_toggle_row` : toute feature avec enfants OU socle devient un
|
|
12
|
+
chevron-toggle. Cliquer `dashboard` replie au lieu de sélectionner ;
|
|
13
|
+
le détail de TOUTE ligne à chevron (layouts compris) est inaccessible ;
|
|
14
|
+
l'icône de kind disparaît → une page se lit comme un layout.
|
|
15
|
+
2. **Placement transitif inexpliqué.** `geo` est placé sous `planning_nav`
|
|
16
|
+
(LCA de {planning, tournees}, atteints VIA planning_engine) mais le
|
|
17
|
+
hover et le détail ne montrent que le direct → le lecteur ne peut pas
|
|
18
|
+
reconstituer le pourquoi. Vérifié : `planning.uses = [planning_engine]`,
|
|
19
|
+
geo absent des deux pages.
|
|
20
|
+
3. **Donnée sans vue.** Badge « 6 routes » : le compte s'affiche, la liste
|
|
21
|
+
(`AppGraph.routes`, elle existe) n'est visible nulle part.
|
|
22
|
+
4. **`errors` mélangé aux pages de nav.** Exact au fond (`@error_page(404,
|
|
23
|
+
layout=shell)` → le 404 SE REND dans le shell) mais présenté comme une
|
|
24
|
+
page navigable.
|
|
25
|
+
|
|
26
|
+
**Cause racine** : deux relations de natures différentes — la CONTENANCE
|
|
27
|
+
(un arbre, déclaré par `layout=`/`parent=`) et la DÉPENDANCE (un graphe,
|
|
28
|
+
déclaré par `uses`/`reads`) — fondues dans UNE seule structure spatiale.
|
|
29
|
+
Le LCA est une analyse ; en faire la position produit des placements
|
|
30
|
+
inexplicables, des pages-dossiers et des clics contradictoires.
|
|
31
|
+
|
|
32
|
+
## Prior art — ce que font les systèmes réels (vérifié sur docs officielles,
|
|
33
|
+
recherche 2026-07-05)
|
|
34
|
+
|
|
35
|
+
- **Encore.dev** : les frontières (services = dossiers) et les ressources
|
|
36
|
+
(API/DB/pubsub) sont déclarées en code ; **les arêtes ne sont JAMAIS
|
|
37
|
+
déclarées — toujours dérivées par analyse statique** (« 100% accuracy…
|
|
38
|
+
any deviation is caught as a compilation error »). Dans Flow : boxes +
|
|
39
|
+
flèches (pleine = appel API, tiretée = pubsub). Les « systems » (dossiers)
|
|
40
|
+
sont explicitement non-sémantiques. Pas de placement par usage.
|
|
41
|
+
- **Backstage** : tout est **déclaré** en YAML ; vocabulaires disjoints
|
|
42
|
+
contenance (`partOf`/`hasPart`) vs dépendance (`dependsOn`,
|
|
43
|
+
`consumesApis`) ; visualisation = vues de voisinage par entité avec
|
|
44
|
+
filtres, pas un arbre global. **Aucune vérification contre le code** —
|
|
45
|
+
le mode d'échec canonique du catalogue déclaré-seulement.
|
|
46
|
+
- **Nx** : arêtes **dérivées des imports** ; intention **déclarée** (tags) ;
|
|
47
|
+
`enforce-module-boundaries` (lint) **réconcilie les deux** — le seul des
|
|
48
|
+
quatre où l'architecture déclarée est machine-vérifiée contre le code.
|
|
49
|
+
Groupes visuels = dossiers (cosmétique) ; **provenance d'arête** : cliquer
|
|
50
|
+
une dépendance montre quels fichiers l'ont créée ; traçage de chemin
|
|
51
|
+
start→end à la demande (pas dessiné par défaut).
|
|
52
|
+
- **C4** : la contenance vit sur l'**axe du zoom** (un diagramme = l'intérieur
|
|
53
|
+
d'UN système) ; « large diagrams are usually hard to interpret… nobody is
|
|
54
|
+
going to look at it » ; remède officiel : plusieurs diagrammes simples
|
|
55
|
+
issus d'**un seul modèle** (Structurizr).
|
|
56
|
+
|
|
57
|
+
**Leçons appliquées à Bretzel** :
|
|
58
|
+
1. contenance et dépendance = deux axes, jamais fondus (→ Fautes v3) ;
|
|
59
|
+
2. le pattern gagnant = déclaré (intention) + dérivé (réalité) + **lint
|
|
60
|
+
réconciliateur** (→ L1/L2 ci-dessous — sans L2, `uses=` devient un
|
|
61
|
+
catalog-info.yaml : un mensonge bien intentionné) ;
|
|
62
|
+
3. la liberté du repo est sûre précisément parce que la vérité ne vient
|
|
63
|
+
pas des dossiers ;
|
|
64
|
+
4. un modèle, plusieurs vues focalisées — pas de méga-carte ;
|
|
65
|
+
5. **une arête doit pouvoir se prouver** (provenance : quel import/état l'a
|
|
66
|
+
créée) — à brancher sur L2 quand le lint existera.
|
|
67
|
+
|
|
68
|
+
**Écart assumé (Option A)** : le prior art strict ne niche jamais par usage ;
|
|
69
|
+
l'Option A place des GROUPES socle dans l'arbre, accrochés aux layouts.
|
|
70
|
+
C'est une projection étiquetée de l'axe dépendance (connecteur tireté +
|
|
71
|
+
eyebrow « socle », jamais sous une page), pas une prétention de contenance —
|
|
72
|
+
choisie sciemment pour l'effet spatial validé par l'utilisateur.
|
|
73
|
+
|
|
74
|
+
## Le modèle v4 — 3 questions → 3 vues, 1 manifeste arbitré
|
|
75
|
+
|
|
76
|
+
### Les rôles (l'API `Feature` ne change pas)
|
|
77
|
+
|
|
78
|
+
Les 10 kinds se répartissent en 3 comportements de modèle :
|
|
79
|
+
|
|
80
|
+
| rôle | kinds | se comporte comme |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| **ANCRE** (se rend) | shell, layout, page, error | nœud de l'arbre de rendu |
|
|
83
|
+
| **SOCLE** (se consomme) | data, state, logic, facade, infra | feuille de dépendance |
|
|
84
|
+
| **ENTRÉE** (se déclenche) | job | point d'entrée hors HTTP |
|
|
85
|
+
|
|
86
|
+
### Le manifeste : contrat ↔ réalité ↔ lint
|
|
87
|
+
|
|
88
|
+
- **Déclaré** (l'intention, 5 champs) : `name, kind, provides, uses, reads`.
|
|
89
|
+
- **Dérivé** (les faits, gratuits) : arbre de rendu (marks `@page`/`@layout`),
|
|
90
|
+
routes, fichier par symbole (`__module__` de chaque provide), **portée**
|
|
91
|
+
(LCA → badge `global | branche <layout> | privé à <page>`), chaînes de
|
|
92
|
+
consommation transitives (« geo ← planning_engine ← planning, tournées »).
|
|
93
|
+
- **Linté** (la doc ne peut pas mentir) — **LIVRÉ 2026-07-05** :
|
|
94
|
+
- L1 — `undeclared_provides()` : routable couvert par aucune Feature →
|
|
95
|
+
WARN au startup + section « ⚠ non déclaré » dans la carte
|
|
96
|
+
(`app.undeclared_pages`). Silencieux si l'app n'utilise pas les
|
|
97
|
+
Features (pas de sermon rétroactif).
|
|
98
|
+
- L2 — `dependency_drift()` : `uses`/`reads` déclarés vs **imports
|
|
99
|
+
réels** (AST des modules de chaque feature, via `sys.modules`) →
|
|
100
|
+
WARN dans les deux sens (missing = importé-non-déclaré, stale =
|
|
101
|
+
déclaré-non-importé). Excusés : soi-même, le parent de RENDU (le lien
|
|
102
|
+
`layout=` est déclaré par le mark), les modules hors features.
|
|
103
|
+
Dev-mode only (`config.debug`). Limites documentées : l'union
|
|
104
|
+
uses∪reads est comparée (la nuance n'est pas dérivable d'un import) ;
|
|
105
|
+
les imports sous `TYPE_CHECKING` comptent.
|
|
106
|
+
- Garde permanente : `test_dependency_drift_clean_on_real_examples`
|
|
107
|
+
force les contrats de mad à coller à leurs imports, pour
|
|
108
|
+
toujours.
|
|
109
|
+
|
|
110
|
+
C'est la réponse à « flexible ET manifeste clair » : le repo reste libre
|
|
111
|
+
(les dossiers ne portent AUCUNE sémantique), le manifeste reste 5 champs,
|
|
112
|
+
et le framework **arbitre** contrat contre réalité — c'est ce qui rend la
|
|
113
|
+
doc vivante fiable pour un humain comme pour une IA.
|
|
114
|
+
|
|
115
|
+
### Vue 1 — INTERFACE : l'arbre de rendu PUR
|
|
116
|
+
|
|
117
|
+
- shell → layouts → pages. Une page n'est **jamais** un dossier.
|
|
118
|
+
- Les erreurs : micro-groupe distinct « erreurs » sous leur layout
|
|
119
|
+
(icône ⚠, pas mélangées aux pages de nav).
|
|
120
|
+
- **Grammaire de clic** : clic ligne = TOUJOURS sélection/détail ;
|
|
121
|
+
le chevron est une petite cible séparée (layouts uniquement).
|
|
122
|
+
|
|
123
|
+
### Vue 2 — SOCLE : groupé par portée (fork TRANCHÉ — Option A)
|
|
124
|
+
|
|
125
|
+
Chaque feature socle porte un badge de portée dérivé :
|
|
126
|
+
`global` · `branche <layout>` · `privé à <page>`.
|
|
127
|
+
|
|
128
|
+
- **Option A — RETENUE** (2026-07-05, par l'utilisateur ; `examples/shared/app_map_view.py` est construit dessus) : les groupes socle restent dans l'arbre mais
|
|
129
|
+
accrochés aux **layouts uniquement** (shell, planning_nav…) — jamais
|
|
130
|
+
sous une page ; le privé-à-une-page remonte au layout parent avec badge
|
|
131
|
+
« privé à dashboard ». Garde l'effet spatial validé
|
|
132
|
+
(account_data-sous-account_nav) sans pages-dossiers.
|
|
133
|
+
- **Option B** : zone Socle séparée sous l'arbre, groupée par portée.
|
|
134
|
+
L'arbre reste 100 % rendu ; le lien spatial est remplacé par badges+hover.
|
|
135
|
+
- **Option C** : les deux, avec un toggle de vue.
|
|
136
|
+
|
|
137
|
+
### Vue 3 — DÉTAIL & FLUX : l'explication
|
|
138
|
+
|
|
139
|
+
- Détail (clic) : contrat + **fichier par symbole** (chemin cliquable) +
|
|
140
|
+
**consommateurs transitifs avec la chaîne via** — c'est ce qui rend le
|
|
141
|
+
placement de `geo` lisible.
|
|
142
|
+
- Hover : éclaire le direct en fort + le transitif en atténué.
|
|
143
|
+
- Badge routes **cliquable** → table `route → feature`.
|
|
144
|
+
- Jobs : listés comme « entrées », avec ce qu'ils déclenchent.
|
|
145
|
+
|
|
146
|
+
## Ce que la v4 SUPPRIME (simplification du composant)
|
|
147
|
+
|
|
148
|
+
- L'injection du socle dans la récursion de rendu (la cause de la moitié
|
|
149
|
+
des bugs) — l'arbre redevient trivial.
|
|
150
|
+
- Le double-rôle du clic — un seul comportement par cible.
|
|
151
|
+
- Les compteurs sans vue.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Structure d'une app Bretzel — tout est feature, le contrat est déclaré
|
|
2
|
+
|
|
3
|
+
**À lire** quand tu démarres une app, ajoutes une feature, ou hésites sur où
|
|
4
|
+
mettre un fichier.
|
|
5
|
+
|
|
6
|
+
> ⚠️ **Réécrit le 2026-08-01.** La version précédente décrivait un modèle
|
|
7
|
+
> que le code avait dépassé : elle ne mentionnait **nulle part** le contrat
|
|
8
|
+
> `Feature` — qui fait échouer le boot quand il est violé —, prescrivait
|
|
9
|
+
> `h-screen` là où les shells réels faisaient `fixed inset-0` (et où
|
|
10
|
+
> `traps.md` conclut « ne PAS re-reverter » — depuis le 2026-08-23 c'est
|
|
11
|
+
> `ui.viewport` qui le porte), et bannissait `shared/` avec
|
|
12
|
+
> trois contre-exemples vivants. Références vérifiées : `examples/crm`
|
|
13
|
+
> pour la structure, `examples/docs` et `examples/playground` pour le
|
|
14
|
+
> reste.
|
|
15
|
+
>
|
|
16
|
+
> ⚠️ **Troisième app de référence en deux semaines** : une app à plat
|
|
17
|
+
> jusqu'au 2026-09-07, `mad` jusqu'au 2026-09-10, toutes deux parties à
|
|
18
|
+
> l'élagage. Une doc de structure ancrée sur une DÉMO est réécrite
|
|
19
|
+
> chaque fois qu'une démo tombe, et une démo est là pour pouvoir
|
|
20
|
+
> tomber. `crm` est l'instrument d'usage réel — la seule app
|
|
21
|
+
> d'`examples/` qui ne relève pas de la règle d'élagage.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 1. Le principe
|
|
26
|
+
|
|
27
|
+
**Une feature = un dossier ou un fichier qui se décrit lui-même.** Elle
|
|
28
|
+
déclare ce qu'elle expose, ce dont elle a besoin, et se décore elle-même
|
|
29
|
+
(`@page` / `@layout` / `@error`). Aucune feature n'importe l'instance d'app.
|
|
30
|
+
`main.py` est le seul fichier qui la connaît, et il ne fait qu'une chose :
|
|
31
|
+
`app.include(...)`.
|
|
32
|
+
|
|
33
|
+
Il n'y a pas de « type spécial » de feature. Un **shell est une feature** qui
|
|
34
|
+
expose une région (`ui.outlet()`). Une source de données est une feature qui
|
|
35
|
+
n'expose aucune page. La hiérarchie ne vit pas dans l'arborescence, elle vit
|
|
36
|
+
dans le **contrat**.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Le contrat `Feature` — le cœur
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from bretzel import Feature
|
|
44
|
+
|
|
45
|
+
feature = Feature(
|
|
46
|
+
name="notes",
|
|
47
|
+
kind="page",
|
|
48
|
+
provides=[notes_page, NotesDraft], # ce que les autres peuvent importer
|
|
49
|
+
uses=["notes_data"], # les features dont je dépends
|
|
50
|
+
)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Les six champs : `name`, `kind`, `provides`, `uses`, `reads`, `module`.
|
|
54
|
+
|
|
55
|
+
**Les 10 `kind`** — `shell` · `layout` · `page` · `error` · `state` · `data`
|
|
56
|
+
· `logic` · `infra` · `facade` · `job`. Un `kind` hors de cette liste est
|
|
57
|
+
refusé.
|
|
58
|
+
|
|
59
|
+
**`provides` expose des symboles, pas seulement des `State`.** Une feature de
|
|
60
|
+
données publie légitimement son store, ses fonctions et ses vues :
|
|
61
|
+
`examples/crm/features/accounts_data.py` fait
|
|
62
|
+
`provides=[PatientsRev, list_patients, get_patient, add_patient,
|
|
63
|
+
delete_patient]` — un store de révision, trois lectures et deux écritures
|
|
64
|
+
dans le même contrat. C'est le contrat déclaré qui autorise l'import, pas
|
|
65
|
+
le type du symbole.
|
|
66
|
+
|
|
67
|
+
**Le contrat est validé au démarrage, pas à l'`include`.**
|
|
68
|
+
`validate_features()` tourne dans le lifespan (`server/app.py`) et **fait
|
|
69
|
+
échouer le boot** sur un contrat invalide. Deux linters s'y ajoutent, en
|
|
70
|
+
WARN :
|
|
71
|
+
|
|
72
|
+
| Lint | Ce qu'il attrape |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `undeclared_provides` | un symbole importé par une autre feature sans être dans son `provides` — l'**oubli** de déclaration |
|
|
75
|
+
| `dependency_drift` | un `uses` déclaré qui ne correspond plus aux imports réels (dérivés par AST) — la **dérive** |
|
|
76
|
+
|
|
77
|
+
Les deux ensemble : L1 attrape l'oubli, L2 attrape le mensonge.
|
|
78
|
+
|
|
79
|
+
**`describe_app(features) → AppGraph`** dérive le graphe depuis le contrat ;
|
|
80
|
+
c'est ce qui alimente les pages *app map* de `crm` et
|
|
81
|
+
du playground. Le
|
|
82
|
+
modèle de rendu est dans [`app-map-model.md`](app-map-model.md).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. `main.py` — la racine de composition
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from bretzel import Bretzel
|
|
90
|
+
from myapp.core.theme import THEME
|
|
91
|
+
from myapp.features import shell, home, notes, notes_data
|
|
92
|
+
|
|
93
|
+
app = Bretzel(title="My App", secret_key="…", theme=THEME, mode="dev")
|
|
94
|
+
|
|
95
|
+
# Ajouter une feature = l'ajouter ici. include() lit les contrats Feature(),
|
|
96
|
+
# monte les provides, et VALIDE le graphe au démarrage.
|
|
97
|
+
app.include(shell, notes_data, home, notes)
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
app.run(port=8000, reload=True)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`app.include(*targets)` accepte **cinq formes** : un module, un **nom** de
|
|
104
|
+
module déjà importé (`app.include(__name__)` pour une app mono-fichier), un
|
|
105
|
+
objet **`Feature`**, un callable marqué par un décorateur, ou un itérable de
|
|
106
|
+
tout ça. Idempotent.
|
|
107
|
+
|
|
108
|
+
⚠️ **Le shell s'inclut comme le reste.** Dès qu'une app utilise les contrats,
|
|
109
|
+
un layout DOIT être passé à `include` — sinon il manque au graphe.
|
|
110
|
+
`examples/crm/main.py` inclut son `shell` au même titre que ses pages.
|
|
111
|
+
(Seule `examples/docs`, qui n'utilise pas `Feature`, s'en dispense : son
|
|
112
|
+
layout se résout par référence.)
|
|
113
|
+
|
|
114
|
+
### 3bis. La langue — `lang=` et `texts=`
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
app = Bretzel(title="Mon app", secret_key="…", lang="fr", texts={
|
|
118
|
+
"datatable.clear_filters": "Effacer les filtres",
|
|
119
|
+
"alert.dismiss": "Fermer l'alerte",
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Deux réglages parce qu'il y a **deux natures de texte**, et confondre les
|
|
124
|
+
deux est ce qui produisait la moitié-configurable-moitié-pas :
|
|
125
|
+
|
|
126
|
+
| | qui le produit | comment on le change |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| noms de mois et de jours, axes temporels | **dérivable** d'un code de langue | `lang=` seul |
|
|
129
|
+
| « Clear filters », « No results », « Dismiss alert » | des phrases que **Bretzel a écrites** | `texts=` |
|
|
130
|
+
|
|
131
|
+
`lang=` est une étiquette BCP-47 (`"fr"`, `"pt-BR"`) ; elle pose
|
|
132
|
+
`<html lang>` — un lecteur d'écran y choisit sa voix — et voyage jusqu'aux
|
|
133
|
+
composants. Les quatre composants de date n'ont **plus de table anglaise**
|
|
134
|
+
figée : sans `month_names=` / `weekday_names=`, c'est `Intl` qui nomme,
|
|
135
|
+
dans le navigateur. Python ne peut pas le faire (son module `locale` est
|
|
136
|
+
un état **global au processus**, et Babel serait une dépendance).
|
|
137
|
+
|
|
138
|
+
`texts=` fusionne sur les valeurs anglaises de
|
|
139
|
+
`bretzel.render.texts.DEFAULT_TEXTS`. **Une clé inconnue lève au
|
|
140
|
+
démarrage** : une faute de frappe dans un dict de traduction ne produit
|
|
141
|
+
aucune erreur, et se manifeste seulement par une phrase restée en anglais
|
|
142
|
+
que l'auteur de la traduction ne relira jamais.
|
|
143
|
+
|
|
144
|
+
Ce n'est **pas de l'i18n** (hors périmètre v2.0) : pas de catalogue, pas
|
|
145
|
+
d'extraction, pas de négociation `Accept-Language`, et la seule règle de
|
|
146
|
+
pluriel est *un / autre*. Une app multilingue reste à construire par
|
|
147
|
+
l'app.
|
|
148
|
+
|
|
149
|
+
Côté framework : une phrase neuve dans un composant s'écrit
|
|
150
|
+
`text("mon_composant.ma_clé")` et sa valeur anglaise se pose dans
|
|
151
|
+
`DEFAULT_TEXTS`. L'ordre inverse est interdit par
|
|
152
|
+
`tests/consistency/test_framework_words_go_through_the_table.py`.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 4. L'arborescence
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
my_app/
|
|
160
|
+
├── main.py # Bretzel(...) + app.include(...) — le seul à voir l'app
|
|
161
|
+
├── core/
|
|
162
|
+
│ └── theme.py # THEME = Theme(...) — le seul vrai « global »
|
|
163
|
+
└── features/
|
|
164
|
+
├── shell.py # @layout — expose ui.outlet()
|
|
165
|
+
├── home.py # @page("/") — feature mono-fichier
|
|
166
|
+
├── notes/ # feature en dossier
|
|
167
|
+
│ ├── __init__.py # ré-exporte `feature` (le contrat)
|
|
168
|
+
│ ├── feature.py # Feature(name=, kind=, provides=, uses=)
|
|
169
|
+
│ ├── state.py
|
|
170
|
+
│ ├── logic.py # les handlers, module-level
|
|
171
|
+
│ └── ui.py # le rendu + les décorateurs @page
|
|
172
|
+
└── core/ # les features SANS page, groupées
|
|
173
|
+
└── notes_data/ # (state + logic + ui + feature)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**`features/` peut être imbriqué** — regrouper par domaine est permis.
|
|
177
|
+
⚠️ Aucune app ne le fait aujourd'hui : `mad`, qui portait
|
|
178
|
+
`features/planning/`, est partie le 2026-09-10, et `crm` est plat sur
|
|
179
|
+
ses 25 features. La permission reste ; l'exemple vivant a disparu avec
|
|
180
|
+
elle. Le mot « flat »
|
|
181
|
+
qualifie l'absence de couches techniques (`app/`, `views/`, `controllers/`),
|
|
182
|
+
pas une interdiction de regrouper par domaine.
|
|
183
|
+
|
|
184
|
+
**Mono-fichier ou dossier ?** Dossier au-delà de ~400 LOC, ou dès que le
|
|
185
|
+
contrat devient non trivial. ⚠️ Le seuil est *indicatif* : 37 features
|
|
186
|
+
mono-fichier du playground le dépassent aujourd'hui, dont une à 933 lignes —
|
|
187
|
+
c'est de la dette assumée, pas la règle.
|
|
188
|
+
|
|
189
|
+
**Un `core/` app-level** pour ce qui est vraiment global (le thème). Un
|
|
190
|
+
`features/core/` pour les features sans page. Les deux coexistent.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 5. Le shell — `ui.viewport` et `ui.pane`
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
@layout
|
|
198
|
+
def shell() -> None:
|
|
199
|
+
with ui.viewport():
|
|
200
|
+
with ui.sidebar(collapsible="rail"):
|
|
201
|
+
ui.sidebar_title("Brand", icon=ui.icon("box", size="lg"))
|
|
202
|
+
with ui.sidebar_section(label="MENU"):
|
|
203
|
+
ui.sidebar_item("Home", icon="home", href="/")
|
|
204
|
+
with ui.pane(gap="none", padding="lg"):
|
|
205
|
+
ui.outlet()
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Écrire `ui.viewport()`, c'est choisir un modèle de défilement.** Deux
|
|
209
|
+
existent, et Bretzel garde le second par DÉFAUT :
|
|
210
|
+
|
|
211
|
+
| modèle | qui défile | qui le fait |
|
|
212
|
+
|---|---|---|
|
|
213
|
+
| **document gelé** — `ui.viewport` + `ui.pane` | des régions, chacune la sienne | les outils (VS Code, Slack) ; Quasar en mode `container` |
|
|
214
|
+
| **chrome fixe** (le défaut) | le document | le web (Mantine `AppShell`, shadcn `Sidebar`) |
|
|
215
|
+
|
|
216
|
+
Une page **sans** coque défile normalement, sans que personne n'écrive
|
|
217
|
+
quoi que ce soit. Le modèle gelé s'obtient explicitement, et il se paie :
|
|
218
|
+
il faut une chaîne de hauteurs continue de la racine à la région. Ce qu'il
|
|
219
|
+
achète, c'est **N régions à défilement indépendant** — un maître-détail,
|
|
220
|
+
des colonnes de kanban, un fil de messages à côté d'une liste — que le
|
|
221
|
+
modèle par défaut ne sait pas faire.
|
|
222
|
+
|
|
223
|
+
⚠️ **Les deux chaînes de classes que ce § prescrivait sont mortes le
|
|
224
|
+
2026-08-23**, absorbées dans les deux composants : `fixed inset-0 w-full
|
|
225
|
+
overflow-hidden` (neuf copies) et `flex-1 min-h-0 overflow-y-auto` (dix-
|
|
226
|
+
sept). Le POURQUOI de chaque utilitaire vit maintenant dans le thème du
|
|
227
|
+
composant concerné, en un seul endroit — dont le `min-h-0` load-bearing
|
|
228
|
+
et le `[&>*]:shrink-0` que personne n'écrivait.
|
|
229
|
+
|
|
230
|
+
🔴 **Ne pas revenir à `h-screen` sur la racine d'une coque.** Le piège a
|
|
231
|
+
été reverté **deux fois** vers `h-screen`, chaque fois avec une
|
|
232
|
+
justification que la mesure démentait ; `traps.md` conclut « ne PAS
|
|
233
|
+
re-reverter ». ⚠️ Nuance ajoutée le 2026-08-23 : l'inflation
|
|
234
|
+
(`html.scrollHeight` 7 657 pour un `clientHeight` de 800) **ne s'est pas
|
|
235
|
+
reproduite** dans une forme minimale re-testée en Chromium, donc elle
|
|
236
|
+
venait d'autre chose que du seul `h-screen`. Ça ne rouvre pas le sujet —
|
|
237
|
+
`fixed inset-0` est la forme livrée et elle n'a jamais rien cassé — mais
|
|
238
|
+
la justification écrite n'a pas été re-mesurée.
|
|
239
|
+
|
|
240
|
+
**La nav** (les `sidebar_item`) est listée en dur dans le shell. C'est le
|
|
241
|
+
seul couplage restant, et exactement là que le placement déclaré par chaque
|
|
242
|
+
feature gagnera sa place le jour où on le construira.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 6. Les helpers partagés — autorisés, mais nommés
|
|
247
|
+
|
|
248
|
+
Un dossier de helpers partagés **dans** l'app est légitime dès qu'il évite la
|
|
249
|
+
copie intra-app :
|
|
250
|
+
|
|
251
|
+
- `examples/crm/core/ui.py` — la carte KPI, factorisée.
|
|
252
|
+
- `examples/docs/lib/` — `introspect.py` + `blocks.py` ; l'app documente
|
|
253
|
+
elle-même ce dossier comme partie de son squelette.
|
|
254
|
+
- `examples/shared/app_map_view.py` — partagé **entre** exemples, importé par
|
|
255
|
+
`crm` et le playground.
|
|
256
|
+
|
|
257
|
+
*(L'ancienne règle « pas de `shared/` — banni » avait ces trois
|
|
258
|
+
contre-exemples vivants. Ce qui reste vrai : un dossier de helpers n'est pas
|
|
259
|
+
un fourre-tout — s'il grossit, c'est qu'il contient une feature qu'on n'a pas
|
|
260
|
+
nommée.)*
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 7. Les erreurs
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
@error_page(404, layout=shell)
|
|
268
|
+
def not_found() -> None:
|
|
269
|
+
ui.empty_state("Page introuvable", icon="search-x")
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`abort(403)` (`from bretzel import abort`) lève depuis un handler ou un render pour router vers la page
|
|
273
|
+
d'erreur correspondante.
|
|
274
|
+
|
|
275
|
+
⚠️ **Le catch-all `Exception` est gouverné par `expose_errors`, pas par le
|
|
276
|
+
mode.** `expose_errors` prend son défaut du `mode` mais reste surchargeable
|
|
277
|
+
seul (`Bretzel(mode="dev", expose_errors=False)`). Vrai par défaut, faux
|
|
278
|
+
comme règle.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 8. Le playground fait exception, et c'est écrit
|
|
283
|
+
|
|
284
|
+
`examples/playground` garde un `app/` (`routes.py` + `nav.py` + `layout.py`)
|
|
285
|
+
et un `infra/errors.py`, parce qu'il monte **90 routes** écrites une par
|
|
286
|
+
une. Sa convention propre est dans
|
|
287
|
+
[`playground-pattern.md`](playground-pattern.md).
|
|
288
|
+
|
|
289
|
+
⚠️ La justification a changé le 2026-08-30 : elle disait « ~57 pages
|
|
290
|
+
générées par un sous-système (`features/matrix/`) », et ce
|
|
291
|
+
sous-système a été supprimé. La dérogation tient toujours — un
|
|
292
|
+
catalogue de 90 pages a besoin d'un index écrit — mais plus pour la
|
|
293
|
+
raison qui était écrite ici.
|
|
294
|
+
|
|
295
|
+
C'est une **dérogation assumée pour un catalogue**, pas le modèle d'une app
|
|
296
|
+
produit. Pour une app, la règle du § 4 tient.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 9. Anti-patterns
|
|
301
|
+
|
|
302
|
+
- ❌ `from myapp.main import app` dans une feature. Jamais. Les décorateurs
|
|
303
|
+
sont libres (`from bretzel import page, layout`), `include` fait le reste.
|
|
304
|
+
- ❌ Importer un symbole d'une autre feature sans qu'il soit dans son
|
|
305
|
+
`provides` — `undeclared_provides` le dira.
|
|
306
|
+
- ❌ Déclarer un `uses` qu'on n'utilise plus — `dependency_drift` le dira.
|
|
307
|
+
- ❌ `h-screen` sur la racine du shell (§ 5).
|
|
308
|
+
- ❌ Recréer une couche technique (`views/`, `controllers/`, un `app/` dans
|
|
309
|
+
une app produit).
|
|
310
|
+
- ❌ Un handler en lambda ou en closure — cf. [`handlers.md`](handlers.md).
|
|
311
|
+
|
|
312
|
+
## 10. Checklist — ajouter une feature
|
|
313
|
+
|
|
314
|
+
1. Un fichier `features/<nom>.py`, ou un dossier si le contrat est gros.
|
|
315
|
+
2. Son `Feature(name=, kind=, provides=, uses=)`.
|
|
316
|
+
3. Ses `@page` / `@layout` / `@error`, en important **seulement** `bretzel`.
|
|
317
|
+
4. La ligne dans `app.include(...)` de `main.py`.
|
|
318
|
+
5. Démarrer : un contrat invalide **fait échouer le boot** et te le dit ; un
|
|
319
|
+
`provides` oublié ou un `uses` dérivé sort en WARN.
|