diff --git a/.github/workflows/secure_nx_release.yml b/.github/workflows/secure_nx_release.yml index 8fedd6f361..35b7fe5e8f 100644 --- a/.github/workflows/secure_nx_release.yml +++ b/.github/workflows/secure_nx_release.yml @@ -251,8 +251,8 @@ jobs: fi # PUBLISH: OIDC trusted publishing (default). Avoid any lingering token auth. - - name: nx release publish (OIDC) - if: ${{ steps.ctx.outputs.mode != 'tag' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN != 'true' && (steps.ctx.outputs.mode != 'main' || steps.affected.outputs.count != '0') }} + - name: nx release publish (OIDC, main) + if: ${{ steps.ctx.outputs.mode == 'main' && steps.affected.outputs.count != '0' && vars.USE_NPM_TOKEN != 'true' }} shell: bash env: NPM_CONFIG_PROVENANCE: true @@ -266,11 +266,39 @@ jobs: fi npx nx release publish \ + --projects "${{ steps.affected.outputs.projects }}" \ + --tag "${{ steps.ctx.outputs.dist_tag }}" \ + --access public \ + --verbose + + - name: nx release publish (OIDC, dispatch) + if: ${{ steps.ctx.outputs.mode == 'dispatch' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN != 'true' }} + shell: bash + env: + NPM_CONFIG_PROVENANCE: true + NODE_AUTH_TOKEN: "" + run: | + set -euo pipefail + unset NODE_AUTH_TOKEN + rm -f ~/.npmrc || true + if [[ -n "${NPM_CONFIG_USERCONFIG:-}" ]]; then + rm -f "$NPM_CONFIG_USERCONFIG" || true + fi + + scope="${{ steps.ctx.outputs.scope }}" + if [[ -n "$scope" ]]; then + projects_arg="--projects $scope" + else + projects_arg="" + fi + + npx nx release publish \ + $projects_arg \ --tag "${{ steps.ctx.outputs.dist_tag }}" \ --access public \ --verbose - - name: nx release publish (OIDC, dry-run) + - name: nx release publish (OIDC, dispatch dry-run) if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run && vars.USE_NPM_TOKEN != 'true' }} shell: bash env: @@ -284,28 +312,60 @@ jobs: rm -f "$NPM_CONFIG_USERCONFIG" || true fi + scope="${{ steps.ctx.outputs.scope }}" + if [[ -n "$scope" ]]; then + projects_arg="--projects $scope" + else + projects_arg="" + fi + npx nx release publish \ + $projects_arg \ --tag "${{ steps.ctx.outputs.dist_tag }}" \ --access public \ --verbose \ --dry-run # PUBLISH: token fallback (only when explicitly enabled via repo/environment variable USE_NPM_TOKEN=true). - - name: nx release publish (token) - if: ${{ steps.ctx.outputs.mode != 'tag' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN == 'true' && (steps.ctx.outputs.mode != 'main' || steps.affected.outputs.count != '0') }} + - name: nx release publish (token, main) + if: ${{ steps.ctx.outputs.mode == 'main' && steps.affected.outputs.count != '0' && vars.USE_NPM_TOKEN == 'true' }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + NPM_CONFIG_PROVENANCE: true + run: | + npx nx release publish --projects "${{ steps.affected.outputs.projects }}" --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose + + - name: nx release publish (token, dispatch) + if: ${{ steps.ctx.outputs.mode == 'dispatch' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN == 'true' }} + shell: bash env: NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} NPM_CONFIG_PROVENANCE: true run: | - npx nx release publish --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose + set -euo pipefail + scope="${{ steps.ctx.outputs.scope }}" + if [[ -n "$scope" ]]; then + projects_arg="--projects $scope" + else + projects_arg="" + fi + npx nx release publish $projects_arg --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose - - name: nx release publish (token, dry-run) + - name: nx release publish (token, dispatch dry-run) if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run && vars.USE_NPM_TOKEN == 'true' }} + shell: bash env: NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} NPM_CONFIG_PROVENANCE: true run: | - npx nx release publish --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose --dry-run + set -euo pipefail + scope="${{ steps.ctx.outputs.scope }}" + if [[ -n "$scope" ]]; then + projects_arg="--projects $scope" + else + projects_arg="" + fi + npx nx release publish $projects_arg --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose --dry-run # Tag-triggered publishing: publish the single package referenced by the tag. - name: Build project before publish (tag) diff --git a/apps/automated/src/ui/slider/slider-tests.ts b/apps/automated/src/ui/slider/slider-tests.ts index 0fded42417..df8254add2 100644 --- a/apps/automated/src/ui/slider/slider-tests.ts +++ b/apps/automated/src/ui/slider/slider-tests.ts @@ -6,6 +6,8 @@ import { BindingOptions, View, Page, Observable, EventData, PropertyChangeData, import { Slider } from '@nativescript/core/ui/slider'; // << article-require-slider +import { LinearGradient } from '@nativescript/core/ui/styling/linear-gradient'; + // ### Binding the Progress and Slider value properties to a observable view-model property. // >> article-binding-slider-properties @@ -121,6 +123,67 @@ export function test_set_backgroundColor() { } } +export function test_set_linear_gradient_background() { + const slider = new Slider(); + + // Create a linear gradient programmatically + const gradient = new LinearGradient(); + gradient.angle = Math.PI / 2; // 90 degrees (left to right) + gradient.colorStops = [{ color: new Color('red') }, { color: new Color('green') }, { color: new Color('blue') }]; + + function testAction(views: Array) { + // Set the gradient via the style's backgroundImage + slider.style.backgroundImage = gradient; + + // Verify the slider was created and the gradient was applied + TKUnit.assertNotNull(slider, 'slider should not be null'); + + if (__APPLE__) { + // On iOS, verify that track images were set + const minTrackImage = slider.ios.minimumTrackImageForState(UIControlState.Normal); + const maxTrackImage = slider.ios.maximumTrackImageForState(UIControlState.Normal); + TKUnit.assertNotNull(minTrackImage, 'minimumTrackImage should be set after applying gradient'); + TKUnit.assertNotNull(maxTrackImage, 'maximumTrackImage should be set after applying gradient'); + } else if (__ANDROID__) { + // On Android, verify the progress drawable was modified + const progressDrawable = slider.android.getProgressDrawable(); + TKUnit.assertNotNull(progressDrawable, 'progressDrawable should not be null'); + } + } + + helper.buildUIAndRunTest(slider, testAction); +} + +export function test_set_linear_gradient_with_stops() { + const slider = new Slider(); + + // Create a linear gradient with explicit color stops + const gradient = new LinearGradient(); + gradient.angle = 0; // 0 degrees (bottom to top) + gradient.colorStops = [ + { color: new Color('orangered'), offset: { unit: '%', value: 0 } }, + { color: new Color('green'), offset: { unit: '%', value: 0.5 } }, + { color: new Color('lightblue'), offset: { unit: '%', value: 1 } }, + ]; + + function testAction(views: Array) { + slider.style.backgroundImage = gradient; + + // Verify the slider was created + TKUnit.assertNotNull(slider, 'slider should not be null'); + + if (__APPLE__) { + const minTrackImage = slider.ios.minimumTrackImageForState(UIControlState.Normal); + TKUnit.assertNotNull(minTrackImage, 'minimumTrackImage should be set after applying gradient with stops'); + } else if (__ANDROID__) { + const progressDrawable = slider.android.getProgressDrawable(); + TKUnit.assertNotNull(progressDrawable, 'progressDrawable should not be null'); + } + } + + helper.buildUIAndRunTest(slider, testAction); +} + export function test_default_TNS_values() { const slider = new Slider(); TKUnit.assertEqual(slider.value, 0, 'Default slider.value'); diff --git a/apps/toolbox/nativescript.config.ts b/apps/toolbox/nativescript.config.ts index 5eb9475ee3..6eeb31439f 100644 --- a/apps/toolbox/nativescript.config.ts +++ b/apps/toolbox/nativescript.config.ts @@ -12,6 +12,6 @@ export default { packageManager: 'npm', additionalPathsToClean: ['.ns-vite-build'], }, - bundler: 'vite', - bundlerConfigPath: 'vite.config.ts', + // bundler: 'vite', + // bundlerConfigPath: 'vite.config.ts', } as NativeScriptConfig; diff --git a/apps/toolbox/src/app.css b/apps/toolbox/src/app.css index 82f893d56b..21ad68b04e 100644 --- a/apps/toolbox/src/app.css +++ b/apps/toolbox/src/app.css @@ -339,3 +339,32 @@ Button { .text-center { text-align: center; } + +/* Sliders Demo Page Styles */ +.sliders-demo-page Slider.gradient-slider { + background: linear-gradient(to right, orangered, green, lightblue); +} + +.sliders-demo-page Slider.rainbow-slider { + background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); +} + +.sliders-demo-page Slider.two-color-slider { + background: linear-gradient(to right, #ff6b6b, #4ecdc4); +} + +.sliders-demo-page Slider.sunset-slider { + background: linear-gradient(to right, #f12711, #f5af19); +} + +.sliders-demo-page Slider.ocean-slider { + background: linear-gradient(to right, #2193b0, #6dd5ed); +} + +.sliders-demo-page Slider.purple-slider { + background: linear-gradient(to right, #8e2de2, #4a00e0); +} + +.sliders-demo-page Slider.stops-slider { + background: linear-gradient(to right, red 0%, yellow 50%, green 100%); +} diff --git a/apps/toolbox/src/main-page.xml b/apps/toolbox/src/main-page.xml index 3c72d0b392..43efde9f2c 100644 --- a/apps/toolbox/src/main-page.xml +++ b/apps/toolbox/src/main-page.xml @@ -22,6 +22,7 @@