Skip to content

feat: add calculator example app with switchable modes#86

Merged
mohamedmansour merged 2 commits into
mainfrom
feat/calculator-example
Mar 8, 2026
Merged

feat: add calculator example app with switchable modes#86
mohamedmansour merged 2 commits into
mainfrom
feat/calculator-example

Conversation

@mohamedmansour

@mohamedmansour mohamedmansour commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Add a modern, dark-themed calculator example at examples/app/calculator/ that showcases WebUI SSR + FAST-HTML hydration with a modular mode system.

Architecture:

  • Plugin-like ModeEngine interface (modes/engine.ts) with a registry pattern — adding a new calculator mode requires only one new file and a registerMode() call, with zero UI component changes
  • Standard mode: 4-column grid with basic arithmetic, operator chaining, percent, and sign negation
  • Scientific mode: 5-column grid adding sin/cos/tan (degrees), ln/log, sqrt, x², xʸ, factorial, π, e, parentheses, and memory operations (MC/MR/M+)

Components (FAST-HTML hydration):

  • calc-app: root orchestrator — mode tab switching, keyboard input via document-level keydown listener, delegates to ModeEngine.processInput()
  • calc-display: glassmorphism display panel showing expression history and current value, with backdrop-filter blur
  • calc-button: color-coded by type (number/operator/function/action/equal) with scale+shadow press animation and grid-column span support

Hydration details:

  • prepare() reads @attr values from getAttribute() and child element data from shadowRoot.querySelectorAll() — @attr field initializers run after super() with useDefineForClassFields:false, so they are not available during prepare()
  • Mode tabs are static HTML (not a loop) to avoid a FAST-HTML hydration bug where @observable string arrays in repeat directives cause 'Cannot assign to read only property' errors
  • Keyboard listener on document (not shadowRoot) so calculator input works regardless of focus, with cleanup in disconnectedCallback()

Styling:

  • Dark theme with CSS custom properties for all colors, spacing, radii, shadows, and transitions
  • Button types: numbers (#1e2a4a), operators (#e94560), scientific functions (#533483), actions (#0f3460)
  • Responsive grid switches between 4 and 5 columns via :host([columns]) attribute selector
image

Add a modern, dark-themed calculator example at examples/app/calculator/
that showcases WebUI SSR + FAST-HTML hydration with a modular mode system.

Architecture:
- Plugin-like ModeEngine interface (modes/engine.ts) with a registry
  pattern — adding a new calculator mode requires only one new file and
  a registerMode() call, with zero UI component changes
- Standard mode: 4-column grid with basic arithmetic, operator chaining,
  percent, and sign negation
- Scientific mode: 5-column grid adding sin/cos/tan (degrees), ln/log,
  sqrt, x², xʸ, factorial, π, e, parentheses, and memory operations
  (MC/MR/M+)

Components (FAST-HTML hydration):
- calc-app: root orchestrator — mode tab switching, keyboard input via
  document-level keydown listener, delegates to ModeEngine.processInput()
- calc-display: glassmorphism display panel showing expression history
  and current value, with backdrop-filter blur
- calc-button: color-coded by type (number/operator/function/action/equal)
  with scale+shadow press animation and grid-column span support

Hydration details:
- prepare() reads @attr values from getAttribute() and child element
  data from shadowRoot.querySelectorAll() — @attr field initializers
  run after super() with useDefineForClassFields:false, so they are
  not available during prepare()
- Mode tabs are static HTML (not a <for> loop) to avoid a FAST-HTML
  hydration bug where @observable string arrays in repeat directives
  cause 'Cannot assign to read only property' errors
- Keyboard listener on document (not shadowRoot) so calculator input
  works regardless of focus, with cleanup in disconnectedCallback()

Styling:
- Dark theme with CSS custom properties for all colors, spacing, radii,
  shadows, and transitions
- Button types: numbers (#1e2a4a), operators (#e94560), scientific
  functions (#533483), actions (#0f3460)
- Responsive grid switches between 4 and 5 columns via :host([columns])
  attribute selector
@mohamedmansour mohamedmansour force-pushed the feat/calculator-example branch from 2806a55 to 55d6b90 Compare March 8, 2026 07:37
Comment thread examples/app/calculator/src/calc-app/calc-app.ts Fixed
@mohamedmansour mohamedmansour requested a review from a team March 8, 2026 07:40
…tion or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@mohamedmansour mohamedmansour merged commit b50b13f into main Mar 8, 2026
15 checks passed
@mohamedmansour mohamedmansour deleted the feat/calculator-example branch March 8, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants