All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
odyssey_toggle_buttonnow accepts alayoutattr (:inlinedefault,:stackedfor vertical radio-style list). In stacked mode, options render as a full-width vertical list — each row has a radio circle SVG (filled blue when selected, outlined when not) with the option name to the right and an optional description beneath it. Options support adescriptionkey for stacked mode.- Added
.ody-neutral-{0,50,100,200,250,300,350,400}CSS helper classes for applying Odyssey neutral palette colors to text. - Added complete set of
.ody-*CSS classes covering H1–H3, P1–P3, Mobile Footer, and link variants across regular/medium/bold weights.
AccountUsernow includes alocalefield (optionalString.t()), extracted from the"locale"key in the JWT user claims.PeekAuthplug now assignspeek_verified_claimson the conn — the full verified JWT claims map — giving LiveViews and controllers direct access to raw claim data without re-parsing the token.
odyssey_selectnow accepts an optionallabelattr, wrapping the component in a fieldset with label styling consistent with other Odyssey form components.odyssey_selectnow supports form-integrated mode when afieldattr is provided (likeodyssey_toggle_button). Manages a hidden input for form binding with single and multiple selection via themultipleattr. Standalone mode (viaon_select) remains unchanged.
odyssey_selectcolor dots are now only rendered when the item has a color value. Items without a color field no longer show a grey fallback dot.
- Added
odyssey_product_pickercomponent — a form-integrated product selector with "All" / "Specific" toggle and per-product checkboxes. Expects products as%{id, name, color}atom-keyed maps. Auto-extractsselected_idsfrom the form field value (supports maps, structs, and Ecto changesets) when not explicitly provided. - Added
OdysseyProductPickerJS hook for client-side checkbox ↔ hidden field sync. - Added
odyssey_selectcomponent — a generic dropdown LiveComponent with search/filter. - Added product picker and select demos to the showcase app with LiveView tests.
query_platform/4now handles all 2xx status codes as success, returning{:ok, body}with the raw response body. Previously only200responses with a%{data: data}GraphQL structure were treated as success, causing non-GraphQL platform APIs (e.g. ACME) to incorrectly fall through to the error path.- Added logging to
verify_peek_auth/2andverify_client_request/2to help debug token verification failures. Warning messages now include the specific error reason and config_id context.
odyssey_toggle_buttonwith label no longer makes entire row clickable (was triggering first button when clicking anywhere on the row).odyssey_tabsactive tab now haspointer-events-noneto prevent unnecessary re-navigation when clicking the current tab.
odyssey_activity_pickernow accepts optionalactivitieslist. When provided, skips GraphQL fetch and uses the passed activities directly.install_idis now optional (only required whenactivitiesnot provided).odyssey_tooltipnow wraps inner_block content when provided instead of showing info icon. Use<.odyssey_tooltip text="..."><button>Click me</button></.odyssey_tooltip>to add tooltip to custom elements.odyssey_alerticon now vertically aligns with title text instead of centering on entire content block.
- Added
PeekAppSDK.Client.query_platform/4for cross-brand API querying. Acceptsinstall_id, HTTP method, URL path, and body params.
query_peek_pro/4now automatically retries on 429 rate limit errors with exponential backoff (200ms base, randomized, capped at 2s, up to 5 retries). No API changes required.
odyssey_alertis now content-width by default (flex w-fit) instead of centered full-width. Use the newfullattr for full-width alerts with actions pushed to the right, orclass="w-full"for manual control.
- Added
fullattr toodyssey_alertfor full-width alerts with dismiss/actions pushed to the right. - PostHog now supports
platformfield in partner map (optional, defaults to "peek"). Alldistinct_idvalues are prefixed with platform (e.g., "peek-partner-123", "cng-partner-456"). Runscripts/posthog_migration.jsto alias existing users before deploying. - PostHog
identifyandtracknow setplatformas a property. - Added
scripts/posthog_migration.jsfor migrating existing PostHog data to include platform.
- Fix size of color input to be a square
- Add icon button to encourage squares
- Fix design of daisy modal close button
- Added
odyssey_tooltipcomponent to the demo app showcase with examples for both default and top caret variants. - Added optional
tooltipandtooltip_locationattrs toodyssey_toggle_buttoncomponent. - Added
locationattr toodyssey_tooltipsupportingtop,bottom,left,right(default:top). - Added
dismissableattr and<:action>slot toodyssey_alertfor inline dismiss button and custom actions. - Added
disabledattr toodyssey_toggle_buttonto disable interaction. - Toggle button tooltip now renders after the button group when no label is provided.
- Added
odyssey_color_inputcomponent with blue chevron styling matching dropdown design.
- BREAKING:
odyssey_prefix_inputcomponent no longer applies width styling to the input field itself. Width must now be set on the parent container for full customization control.- Migration: Wrap the component in a container with your desired width class
(e.g.,
<div class="w-[200px] inline-block"><.odyssey_prefix_input ... /></div>)
- Migration: Wrap the component in a container with your desired width class
(e.g.,
- Fixed bug in toggle button where changes weren't propagating correctly inside nested forms.
- Fix link styling to remove underline for back button.
- Events can now be routed to a PostHog project of your choosing by configuring
:posthog_key.PeekAppSDK.Metrics.track_install/2will automatically identify the partner in PostHog on install (setsnameandis_test) and then captureapp.install.PeekAppSDK.Metrics.track/3(partner variant) sends custom events to PostHog and automatically includesdistinct_id,partner_id,partner_name,partner_is_test, andapp_slug.
- BREAKING: Metrics API is now partner-first for key functions:
PeekAppSDK.Metrics.track/3now expects a partner map as the first argument when routing to PostHog (track(partner, event_id, payload)).PeekAppSDK.Metrics.track_install/2now expects a partner map as the first argument and will identify + capture in PostHog when configured.PeekAppSDK.Metrics.track_uninstall/2now expects a partner map as the first argument and will captureapp.uninstallin PostHog when configured.
Migration examples:
- Before:
PeekAppSDK.Metrics.track("order.placed", %{anonymousId: partner_id, level: "info"})PeekAppSDK.Metrics.track_install(partner_id, partner_name, is_test)PeekAppSDK.Metrics.track_uninstall(partner_id, partner_name, is_test)
- After:
PeekAppSDK.Metrics.track(%{external_refid: partner_id, name: partner_name, is_test: is_test}, "order.placed", %{level: "info"})PeekAppSDK.Metrics.track_install(%{external_refid: partner_id, name: partner_name, is_test: is_test})PeekAppSDK.Metrics.track_uninstall(%{external_refid: partner_id, name: partner_name, is_test: is_test})
Note: Legacy arities remain temporarily for compatibility but are considered deprecated and may be removed in the next major release.
- Cosmetic fix for the activity picker component.
- Updated core Odyssey
a.btnbutton link styling inassets/components/core-components.cssto remove underlines from button links per internal design rules.
- Added new icon variants to
odyssey_icon:alert,warning,info,success,cancel,arrow-left,trashcan, andloading.
- Added
odyssey_prefix_inputcomponent for prefixed inputs (for example currency and percentages) in the Odyssey UI library.- Supports both standalone usage and
Phoenix.HTML.Formfield integration. - Documented and showcased in the demo app under the Forms tab with discount and percentage examples.
- Supports both standalone usage and
- Added
odyssey_date_pickercomponent for selecting dates with Odyssey styling and icons.- Supports both standalone usage and
Phoenix.HTML.Formfield integration. - Included in the demo app under the Forms tab with start/expiration date examples.
- Ships with focused tests to keep Odyssey UI coverage high.
- Supports both standalone usage and
- Updated Odyssey
.btndisabled styles so each variant keeps its own color when disabled, instead of using DaisyUI's generic disabled background.
- Fixed a bug where changeset errors were being reset and not displayed by the prefix input when used with a form field; validation errors from the changeset now render correctly.
- Added optional
labelattribute toodyssey_activity_pickercomponent- When a label is provided, the activity picker is automatically wrapped in a fieldset with proper label styling
- Follows the same pattern as Phoenix core input components for consistency
- Maintains 100% backward compatibility - existing usage without labels continues to work unchanged
- Toggle button no longer emits an event when clicking the already-selected option, preventing redundant LiveView events in both standalone and form-integrated usage.
- Added optional
labelattribute toodyssey_toggle_buttonandodyssey_toggle_button_inputcomponents- When a label is provided, the toggle button is automatically wrapped in a fieldset with proper label styling
- Follows the same pattern as Phoenix core input components for consistency
- Maintains 100% backward compatibility - existing usage without labels continues to work unchanged
- Works seamlessly with both standalone and form-integrated usage
- Added
odyssey_toggle_buttoncomponent from Odyssey - Created the beginning of a demo project
- BREAKING: Removed core components - applications should use their own core component file from Phoenix instead of relying on shared components to make Phoenix upgrades easier
- BREAKING: Configuration key
peek_app_keyhas been renamed topeek_api_key - BREAKING: Configuration key
peek_api_urlhas been deprecated in favor ofpeek_api_base_url- The new
peek_api_base_urlshould contain only the base URL (e.g.,"https://apps.peekapis.com") - The SDK automatically appends appropriate paths (e.g.,
/backoffice-gql) for different API endpoints - Migration path:
-
Existing apps using
peek_api_urlwill continue to work for backoffice calls with deprecation warnings -
New features like
update_configuration_statuswill fail with clear migration instructions ifpeek_api_urlis configured -
Update your configuration from:
config :peek_app_sdk, peek_api_url: "https://apps.peekapis.com/backoffice-gql"
to:
config :peek_app_sdk, peek_api_base_url: "https://apps.peekapis.com"
-
- The new
- Support for passing
x-peek-authtoken in request body parameters for scenarios where custom headers cannot be controlled (e.g., form submissions, third-party integrations)- Body parameters take precedence over headers when both are present
- Enables authentication in form submission scenarios and legacy systems
- Configuration validation that prevents use of deprecated
peek_api_urlwith new features - Deprecation warnings when using legacy
peek_api_urlconfiguration for backoffice calls - Clear error messages with migration instructions for deprecated configuration
- URL construction now properly handles base URLs without hardcoded paths