Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:splitter): add splitter component #8987

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

Laffery
Copy link
Collaborator

@Laffery Laffery commented Jan 21, 2025

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Application (the showcase website) / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: #8940

What is the new behavior?

Add splitter component, see https://ant.design/components/splitter

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@Laffery Laffery self-assigned this Jan 21, 2025
@Laffery Laffery added this to the v19.1 milestone Jan 21, 2025
@Laffery Laffery changed the title feat(module:splitter): add splitter component WIP feat(module:splitter): add splitter component Jan 21, 2025
Copy link

zorro-bot bot commented Jan 21, 2025

This preview will be available after the AzureCI is passed.

Copy link

codecov bot commented Jan 21, 2025

Codecov Report

Attention: Patch coverage is 54.95050% with 91 lines in your changes missing coverage. Please review.

Project coverage is 91.56%. Comparing base (f0e9d7f) to head (0341f5e).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
components/splitter/splitter.component.ts 48.12% 74 Missing and 9 partials ⚠️
components/splitter/splitter-bar.component.ts 72.72% 6 Missing ⚠️
components/splitter/utils.ts 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8987      +/-   ##
==========================================
- Coverage   91.94%   91.56%   -0.39%     
==========================================
  Files         559      564       +5     
  Lines       19773    19975     +202     
  Branches     3050     3089      +39     
==========================================
+ Hits        18181    18290     +109     
- Misses       1267     1349      +82     
- Partials      325      336      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Laffery Laffery force-pushed the feat/splitter branch 2 times, most recently from 6f96ac0 to 7da5053 Compare January 21, 2025 07:03
@Laffery Laffery modified the milestones: v19.1, v19.2 Feb 19, 2025
@Laffery Laffery requested a review from CK110 as a code owner March 14, 2025 15:46
})
export class NzSplitterComponent {
/** ------------------- Props ------------------- */
nzLayout = input<NzSplitterLayout>('horizontal');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that inputs are Signals, does it make to declare everything as readonly as you did for outputs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, although readonly isn't required to inputs, we can still use it to make sure type safe during runtime!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. I also like a consistent standard - so readonly by default (where applicable) is how I'd do it.

lazy = input(false);
constrainedOffset = input<number>();

readonly previewTransform = computed(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another opinion: I see that you used protected for resizeStartEvent, but not for properties (those signals) used in templates. This is another candiate for a project-wide standard: should all template-only props/funs be marked as protected, or should all be public?

Copy link
Collaborator Author

@Laffery Laffery Mar 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not expect user to use those internally-used-only props/funs, which are unstable and may be changed/removed in some refactoring PRs.

We only promise that public props/funs declared at the documentation website are compatible in a minor version. So I think they shall be protected.
But sometimes it's not convenient to access them in unit test cases.

TBH, there is currrently no consistant standard in this project.
We cannot get the acknownledge of how many internal apis are being used by user, what we can do as a popular component library is to keep public apis in stable and avoid exposing too many unstable internal apis.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, there is no consistant standard in this project.

Yeah that's what I saw by reading the code.

I would go the route of not bothering with specifying protected, and instead keep everything public because:

  1. sometimes users need access to unstable / internal declarations when NG-ZORRO doesn't behave as expected

  2. you could alternatively mark unstable / internal declarations with TSDoc's @internal

    /** @internal */
    readonly previewTransform = computed(() => {  ... })

    to signify to consumers this is not something they should normally use.
    Additionaly, @internal plays nicely with stripInternal in case in the future you want to get rid of them in the outputted types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, up to you. I was mostly trying to understand if there is a project/team standard, especially now that components are being refactored or created to support signals.

@Laffery
Copy link
Collaborator Author

Laffery commented Mar 16, 2025

@lppedd I'd made changes as your suggestions

@Laffery
Copy link
Collaborator Author

Laffery commented Mar 16, 2025

This pr is nearly completed, all the use cases of antd are implemented.

There are Todos as follows till now:

  • Restore the previous size when expanding a collapsed panel
  • Observe to resize event of the container
  • RTL support
  • Unit test cases

I will add them next week, and I think they do not have a impact on your review of the code, so could you please take a review on this PR if you have time. @Nicoss54 @HyperLife1119 @OriginRing @lppedd

@Laffery Laffery changed the title WIP feat(module:splitter): add splitter component feat(module:splitter): add splitter component Mar 16, 2025
Copy link
Contributor

@lppedd lppedd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some minor comments / nitpicks.

Comment on lines 112 to 113
readonly destroy$ = inject(NzDestroyService);
readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inject-ed services or elements are best kept private imo.
I'd also keep a consistent structure:

  1. private properties
  2. inputs
  3. outputs
  4. component state (props/functions)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the following order

  1. inputs
  2. outputs
  3. private properties
  4. component state (props/functions)

Puting inputs/outputs at the very top makes it clear to the person viewing the code how the component is used, just like a instruction manual

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency over order, so that looks good to me.

@Nicoss54
Copy link
Collaborator

@Laffery @HyperLife1119 does it have a guideline for refactoring the components to support signal ? It will be a great pleasure to help you on this huge reworking.

Take a look and give my review tomorrow if it’s good for you ?

@HyperLife1119
Copy link
Collaborator

@Nicoss54 If there is no special situation, existing components will not be migrated to signals.

@Laffery
Copy link
Collaborator Author

Laffery commented Mar 17, 2025

@Nicoss54 If there is no special situation, existing components will not be migrated to signals.

Agree. That would be a huge work and I don't think the payoff would be great, and there could be unexpected problems introduced.
I think we can leave it as is for now, unless there are bottlenecks in feature implementation or performance.
For new components, we 100% recommend using signals.

@Laffery
Copy link
Collaborator Author

Laffery commented Mar 17, 2025

I think we can leave it as is for now, unless there are bottlenecks in feature implementation or performance. For new components, we 100% recommend using signals.

By the way, material still remains in the original implementation as well

@lppedd
Copy link
Contributor

lppedd commented Mar 17, 2025

Converting to signals during a component's fix or feature addition might be useful to expose unexpected property writes from inside or outside the component itself. But apart from that I agree and I don't see the urgency (also considering signals are not strictly necessary for zoneless).

Comment on lines +31 to +32
(mousedown)="resizeStartEvent($event)"
(touchstart)="resizeStartEvent($event)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use Pointer Event, which supports both mouse and touch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it and the drag doesn't work very well with a touch screen.
Currently antd uses mousedown and touchstart as well, I think we can keep aligning with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants